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.