Skip to content

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.