idanarye/rust-typed-builder

How to make Builder implement `Deserialize`?

Opened this issue · 3 comments

lcmgh commented

Hi!

I want to use the builder together with config-rs to use config from a file as input for the builder. For that the builder struct must support Deserialize. How can I achieve that?

Thanks

I'm not sure what you want to do even makes sense. TypedBuilder has the builder's state (which fields were already set) encoded in its type (in the generic parameters actually), which means it must be known at compile time.

When you think about deserializing a builder, you probably think about something like this:

#[derive(TypedBuilder)]
struct Foo {
    #[builder(default = 1)]
    bar: i32,
    #[builder(default = 2)]
    baz: i32,
}

assert_eq!(
    Foo::builder(),
    deserialize::<FooBuilder>(r#"{}"#),
);
assert_eq!(
    Foo::builder().bar(3),
    deserialize::<FooBuilder>(r#"{"bar": 3}"#),
);
assert_eq!(
    Foo::builder().baz(4),
    deserialize::<FooBuilder>(r#"{"baz": 4}"#),
);
assert_eq!(
    Foo::builder().bar(3).baz(4),
    deserialize::<FooBuilder>(r#"{"bar": 3, "baz": 4}"#),
);

The problem is that these are four distinct types! deserialize::<FooBuilder>() is dealing with a runtime string, so it can't tell at compile time which fields are set and which aren't.

lcmgh commented

Use case:

  • There is a library that ships a Builder with default values
  • Library client microservice wants to use default values and merge in user configured fields

On client side I want to load config from a file that ovewrites certain fields. With rust-derive-builder I was able to use the Builder type for my settings and merge in user specific attributes from the config file. After retrieving the config I still have to call the build method but I got all the data without any additional setup.

I'm interested in this feature for the same reason as above