idanarye/rust-typed-builder

Set default type for generated Builder generic

Closed this issue · 1 comments

Hi!
Thank you for the great work on the TypedBuilder, it is really nice to use.

I have quite big structs and therefore made a wrapper that boxes the contents, so that it can be passed around without causing stack overflows. I.e.:

#[derive(TypedBuilder)]
struct Inner {
    a: i32,
    b: i32,
}

struct Outer(Box<Inner>);

The issue now is, that I want to build the outer type like this:

let value = Outer::builder().a(3).b(5).build();

There is no way for a custom build function and that can be worked around by adding a function Inner::outer(self) -> Outer, so that would be acceptable, as it would result in:

let value = Outer::builder().a(3).b(5).build().outer();

However, it is not feasible to create the Outer::builder() function, as the generic type needs to be set to a tuple of empty tuples, given the number of fields. The number of fields is sadly unknown, so I cannot generate the builder function appropriately.

So I was wondering if it was possible to somehow provide the default type of the builder via a default type parameter (not sure if that works) or a trait (that should be easy, but a bit clunky). TypedBuilder would generate this:

  1. default type parameter:
struct BlaBuilder<TypedBuilderFields = ((), (), ...)> { ... }
  1. trait:
pub trait BuilderDefaultType {
    type DefaultType;
}

impl<R> BuilderDefaultType for BlaBuilder<R> {
    type DefaultType = ((), (), ...);
}

Then I could use it like this hopefully?:

impl Outer {
    // 1
    pub fn builder() -> InnerBuilder {
        Inner::builder()
    }

    // 2
    pub fn builder() -> <InnerBuilder as BuilderDefaultType>::DefaultType {
        Inner::builder()
    }
}

What do you think about this, is this something that is possible and would be accepted? Especially variant 1 should not really change anything besides adding the default type parameter and should be easy to add without any harm, right?

I guess the .outer() function can be replaced by the solution of #52 ?