colin-kiegel / rust-derive-builder

derive builder implementation for rust structs
https://colin-kiegel.github.io/rust-derive-builder/
Apache License 2.0
1.32k stars 88 forks source link

Incompatibility between `setter(strip_option)` and `setter(each)` #213

Closed SteadBytes closed 2 years ago

SteadBytes commented 3 years ago

Combining setter(strip_option and setter(each) to provide an "append" API for an optional field fails to compile:

error[E0599]: no method named `extend` found for mutable reference `&mut Option<Vec<i32>>` in the current scope

Example

Provide a builder method FooBuilder.bar for appending to FooBuilder.bars one item at a time whilst defaulting to None if never called.

#[macro_use]
extern crate derive_builder;

#[derive(Debug, PartialEq, Default, Builder)]
struct Foo {
    #[builder(default, setter(strip_option, each = "bar"))]
    bars: Option<Vec<i32>>,
}

fn main() {
    assert_eq!(
        FooBuilder::default().build().unwrap(),
        Foo { bars: None },
        "None if unset"
    );

    assert_eq!(
        FooBuilder::default().bar(1).bar(2).bar(3).build.unwrap(),
        Foo {[]
            bars: Some(vec![1, 2, 3])
        },
        "Some(Vec<i32>) when set"
    );
}

Apologies if I'm missing something to make this work. Otherwise, I think this would be a useful feature to support if possible.