Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optionally transform Extend fields to add items one by one #46

Draft
wants to merge 19 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
486480b
Rudimentarily adjusted parser to accept `strip_extend` with optional …
Tamschi Jan 16, 2021
c824836
Implement `strip_extend` proof of concept
Tamschi Jan 17, 2021
03e0e58
Rework `strip_extend` into `strip_collection`, which has stricter typ…
Tamschi Jan 18, 2021
b19a01b
Use `FromIterator` to create initial stripped collection iff neither …
Tamschi Jan 18, 2021
4376566
Accept any valid `Extend::extend` parameter in repeat setter calls
Tamschi Jan 18, 2021
8e4b301
Accept e.g. `strip_collection(from_first = |first| vec![first])` inst…
Tamschi Jan 22, 2021
7635462
Merge branch 'master' into extend-field-buildup
Tamschi Feb 8, 2021
a3d3e31
Rework `strip_collection` into `extend`, allow extending with an iter…
Tamschi Feb 4, 2021
c9bba54
Accept any matching `IntoIterator` instead of just matching `Iterator…
Tamschi Feb 8, 2021
586d3dc
Add some `extend` tests, fix issues with type inference and improve c…
Tamschi Feb 13, 2021
23ca53a
Ignore field default in automatic extend initialisers
Tamschi Feb 13, 2021
094a827
Add generics support in combination with `extend`
Tamschi Feb 13, 2021
4a2afb0
Remove extra parentheses
Tamschi Feb 13, 2021
a3006a1
Support combining `strip_option` and `extend` on the same field
Tamschi Feb 13, 2021
9bb9dbf
cargo +nightly fmt
Tamschi Feb 13, 2021
4c67cf4
Assert `strip_option` flag inside `type_from_inside_option`
Tamschi Feb 13, 2021
c8abc4d
Mention single item setter name in `early_build_error_message`
Tamschi Feb 14, 2021
8cc816a
Merge branch 'master' into extend-field-buildup
Tamschi Jun 22, 2021
3a8ff5f
Merge remote-tracking branch 'upstream/master' into extend-field-buildup
Tamschi Nov 11, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 79 additions & 3 deletions examples/example.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
use std::{collections::HashMap, iter};

use typed_builder::TypedBuilder;

macro_rules! extend {
[$init:expr; $($expr:expr),*$(,)?] => {{
let mut e = $init;
$(e.extend(iter::once($expr));)*
e
}};
}

#[derive(PartialEq, TypedBuilder)]
struct Foo {
// Mandatory Field:
Expand All @@ -13,16 +23,82 @@ struct Foo {
// Or you can set the default
#[builder(default = 20)]
z: i32,

// #[builder(default)] without parameter - don't require this field
// #[builder(setter(extend))] without parameter - start with the default and extend from there
#[builder(default, setter(extend(from_first, item_name = i0)))]
v0: Vec<i32>,

// No `default`: This field must be set at least once.
// You can explicitly create the collection from the first item (but this is not required even without `default`).
#[builder(setter(extend(from_first = |first| vec![first])))]
v1: Vec<i32>,

// Other `Extend` types are also supported.
#[builder(default, setter(extend))]
h: HashMap<i32, i32>,
}

fn main() {
assert!(Foo::builder().x(1).y(2).z(3).build() == Foo { x: 1, y: Some(2), z: 3 });
assert!(
Foo::builder().x(1).y(2).z(3).i0(4).v1_item(5).h_item((6, 7)).build()
== Foo {
x: 1,
y: Some(2),
z: 3,
v0: vec![4],
v1: vec![5],
h: extend![HashMap::new(); (6, 7)],
}
);

// Change the order of construction:
assert!(Foo::builder().z(1).x(2).y(3).build() == Foo { x: 2, y: Some(3), z: 1 });
assert!(
Foo::builder().z(1).x(2).h_item((3, 4)).v1_item(5).i0(6).y(7).build()
== Foo {
x: 2,
y: Some(7),
z: 1,
v0: vec![6],
v1: vec![5],
h: extend![HashMap::new(); (3, 4)],
}
);

// Optional fields are optional:
assert!(Foo::builder().x(1).build() == Foo { x: 1, y: None, z: 20 });
assert!(
Foo::builder().x(1).v1_item(2).build()
== Foo {
x: 1,
y: None,
z: 20,
v0: vec![],
v1: vec![2],
h: HashMap::new(),
}
);

// Extend fields can be set multiple times:
assert!(
Foo::builder()
.x(1)
.i0(2)
.i0(3)
.i0(4)
.v1_item(5)
.v1_item(6)
.h_item((7, 8))
.h_item((9, 10))
.build()
== Foo {
x: 1,
y: None,
z: 20,
v0: vec![3, 4],
v1: vec![5, 6],
h: extend![HashMap::new(); (7, 8), (9, 10)],
}
);

// This will not compile - because we did not set x:
// Foo::builder().build();
Expand Down
Loading