Positional Members ​
You can let the caller pass some values as positional parameters to the starting function, that creates the builder or to the finishing function, that consumes it.
Starting function ​
Use #[builder(start_fn)]
to move some members to the parameters of the starting function.
rust
use bon::Builder;
#[derive(Builder)]
// Top-level attribute to give a custom name for the starting function
#[builder(start_fn = with_coordinates)]
struct Treasure {
// Member-level attributes to move members
// to the parameters of `with_coordinates()`
#[builder(start_fn)]
x: u32,
#[builder(start_fn)]
y: u32,
label: Option<String>,
}
let treasure = Treasure::with_coordinates(2, 9)
.label("oats".to_owned())
.build();
assert_eq!(treasure.x, 2);
assert_eq!(treasure.y, 9);
assert_eq!(treasure.label.as_deref(), Some("oats"));
TIP
There are two versions of the #[builder(start_fn)]
used here: top-level and member-level. They have different meanings.
Finishing function ​
Use #[builder(finish_fn)]
to move some members to the parameters of the finishing function.
rust
use bon::Builder;
#[derive(Builder)]
// Top-level attribute to give a custom name for the finishing function
#[builder(finish_fn = located_at)]
struct Treasure {
// Member-level attributes to move members
// to the parameters of `located_at()`
#[builder(finish_fn)]
x: u32,
#[builder(finish_fn)]
y: u32,
label: Option<String>,
}
let treasure = Treasure::builder()
.label("oats".to_owned())
.located_at(2, 9);
assert_eq!(treasure.x, 2);
assert_eq!(treasure.y, 9);
assert_eq!(treasure.label.as_deref(), Some("oats"));
TIP
There are two versions of the #[builder(finish_fn)]
used here: top-level and member-level. They have different meanings.