idanarye / rust-typed-builder

Compile-time type-checked builder derive
https://crates.io/crates/typed-builder
Apache License 2.0
904 stars 52 forks source link

Way to mark all Option fields as default (unless explicitly specified). #108

Open koenichiwa opened 1 year ago

koenichiwa commented 1 year ago

Is there a way to mark all Option fields as default?

I have a struct with about 30 optional fields and just 2 non-optional fields (I'm parsing/creating a specific type of xml file), and I'm not even talking about the nested structs.

I wanted my code to look cleaner, so I thought deriving some sort of builder would help me. But needing to annotate every field with #[builder(default)] seems like a lot of boilerplate.

idanarye commented 1 year ago

I understand your usecase, but I don't even do auto-Option-detection for strip_options. Trying to give special treatment to a generic type using syntax detection alone is a can of worms I with to avoid...

In your case, I'd just do something like this:

use typed_builder::TypedBuilder;

#[derive(TypedBuilder, Debug)]
#[builder(field_defaults(default))]
struct Foo {
    #[builder(!default)]
    field1: u32,
    #[builder(!default)]
    field2: u32,
    field3: Option<u32>,
    field4: Option<u32>,
    field5: Option<u32>,
    field6: Option<u32>,
    field7: Option<u32>,
    field8: Option<u32>,
    field9: Option<u32>,
    field10: Option<u32>,
}

fn main() {
    println!("{:#?}", Foo::builder().field1(1).field2(2).build());

    // These will fail to compile:
    println!("{:?}", Foo::builder().field1(1).build());
    println!("{:?}", Foo::builder().field2(2).build());
}