### Starting Function: Move Members to Parameters (Struct, Rust) Source: https://bon-rs.com/guide/basics/positional-members Demonstrates using `#[builder(start_fn)]` on a struct to move members to the parameters of a custom-named starting function. This allows direct initialization of specific fields when creating the builder instance. Dependencies include the `bon::Builder` derive macro. ```rust #[derive(bon::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, } 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")); ``` -------------------------------- ### Manual Into Conversions for Function Builders Source: https://bon-rs.com/guide/basics/into-conversions Illustrates manual `into()` conversions for function-based builders generated by `#[bon::builder]`. This example shows the equivalent usage to the struct builder, converting string literals and paths before calling the function. ```rust use std::path::PathBuf; #[bon::builder] fn example( name: String, description: String, path: PathBuf, ) {} example() .name("Bon".to_owned()) .description("Awesome crate 🐱".to_string()) .path("/path/to/bon".into()) .call(); ``` -------------------------------- ### Rust: Original Function Signatures Comparison Source: https://bon-rs.com/guide/patterns/optional-generic-members Illustrates the difference between the 'Good' and 'Bad' example function signatures. The 'Good' example uses a concrete `Option`, while the 'Bad' example uses a generic `Option` requiring manual conversion within the function body. ```rust #[bon::builder] fn good(#[builder(into)] x1: Option) { // ... } ``` ```rust #[bon::builder] fn bad>(x1: Option) { let x1 = x1.map(Into::into); // ... } ``` -------------------------------- ### Starting Function: Move Members to Parameters (Function, Rust) Source: https://bon-rs.com/guide/basics/positional-members Illustrates using `#[builder(start_fn)]` on a standalone function to move members to its parameters. This approach defines a function that directly creates a builder and allows passing specific arguments during its invocation. Requires the `bon::builder` attribute. ```rust // The starting function's name is the name of the underlying function itself, // that's why we don't really need `#[builder(start_fn = ...)] rename here // unlike in #[derive(Builder)] syntax case. #[bon::builder] fn display_treasure( // Member-level attributes to move members // to the parameters of `display_treasure()` #[builder(start_fn)] x: u32, #[builder(start_fn)] y: u32, label: Option, ) -> String { format!("{x}, {y}, {label:?}") } let treasure = display_treasure(2, 9) .label("oats".to_owned()) .call(); assert_eq!(treasure, r###"2, 9, Some("oats")"###) ``` -------------------------------- ### Starting Function: Move Members to Parameters (Impl Block, Rust) Source: https://bon-rs.com/guide/basics/positional-members Shows how to use `#[builder(start_fn)]` within an `impl` block for a struct, moving members to the function's parameters. This enables builder pattern usage directly on methods. Relies on the `#[bon::bon]` attribute. ```rust struct Example; #[bon::bon] impl Example { // The starting function's name is the name of the underlying function itself, // that's why we don't really need `#[builder(start_fn = ...)] rename here // unlike in #[derive(Builder)] syntax case. #[builder] fn display_treasure( // Member-level attributes to move members // to the parameters of `display_treasure()` #[builder(start_fn)] x: u32, #[builder(start_fn)] y: u32, label: Option, ) -> String { format!("{x}, {y}, {label:?}") } } let treasure = Example::display_treasure(2, 9) .label("oats".to_owned()) .call(); assert_eq!(treasure, r###"2, 9, Some("oats")"###) ``` -------------------------------- ### Manual Into Conversions for Method Builders Source: https://bon-rs.com/guide/basics/into-conversions Presents manual `into()` conversions within an `impl` block using the `#[bon::bon]` attribute and `#[builder]` macro. This demonstrates how to achieve the same conversion behavior for methods acting as builders. ```rust use std::path::PathBuf; struct Example; #[bon::bon] impl Example { #[builder] fn example( name: String, description: String, path: PathBuf, ) {} } Example::example() .name("Bon".to_owned()) .description("Awesome crate 🐱".to_string()) .path("/path/to/bon".into()) .call(); ``` -------------------------------- ### Rust Collection Builder with buildstructor Source: https://bon-rs.com/guide/alternatives Illustrates how `buildstructor` generates methods to build collections element by element. In this example, the `friend` method is generated for the `friends` Vec field, allowing individual additions. ```rust use buildstructor::Builder; #[derive(Builder)] struct User { friends: Vec } fn main() { User::builder() .friend("Foo") .friend("Bar") .friend("`String` value is also accepted".to_owned()) .build(); } ``` -------------------------------- ### Function Argument Setter with Custom Conversion - Rust Source: https://bon-rs.com/guide/basics/custom-conversions Illustrates using #[builder(with)] on a function argument for custom conversion logic. The example shows a function `example` where the `point` argument uses a closure to convert two `u32` values into a `Point` struct. The `call()` method is used to invoke the builder. ```rust struct Point { x: u32, y: u32, } #[bon::builder] fn example( #[builder(with = |x: u32, y: u32| Point { x, y })] point: Point, ) -> Point { point } let value = example() .point(2, 3) .call(); assert_eq!(value.x, 2); assert_eq!(value.y, 3); ``` -------------------------------- ### Rust: Generated Builder Code Comparison Source: https://bon-rs.com/guide/patterns/optional-generic-members Compares the simplified generated builder code for `#[builder(into)]` and `Option` approaches. Highlights that `#[builder(into)]` results in a builder without generic parameters in the starting function and performs `into()` conversions early in setters, whereas `Option` carries generic parameters and defers conversions. ```rust fn good() -> GoodBuilder { /**/ } impl GoodBuilder { fn x1(self, value: impl Into) -> GoodBuilder> { GoodBuilder { /* other fields */, __x1: value.into() } } } ``` ```rust fn bad() -> BadBuilder { /**/ } impl, S: State> BadBuilder { fn x1(self, value: T) -> BadBuilder> { BadBuilder { /* other fields */, __x1: value } } } ``` -------------------------------- ### Manual Into Conversions for Struct Builders Source: https://bon-rs.com/guide/basics/into-conversions Demonstrates manual `into()` conversions for `String` and `PathBuf` members when using `bon::Builder` on a struct. It shows how to use `.to_owned()`, `.to_string()`, and `.into()` to convert string literals and paths to the required types. ```rust use std::path::PathBuf; #[derive(bon::Builder)] struct Example { name: String, description: String, path: PathBuf, } Example::builder() .name("Bon".to_owned()) .description("Awesome crate 🐱".to_string()) .path("/path/to/bon".into()) .build(); ``` -------------------------------- ### Derive Builder with Bon.rs Source: https://bon-rs.com/guide/typestate-api/custom-methods This Rust code snippet shows the basic usage of the `#[derive(Builder)]` macro from the 'bon' crate to generate a builder for a struct. It defines a struct 'Example' with a single field 'x1' of type u32. The macro automatically generates builder methods based on the struct fields. ```rust use bon::Builder; #[derive(Builder)] struct Example { x1: u32, } ``` -------------------------------- ### Impl Method Setter with Custom Conversion - Rust Source: https://bon-rs.com/guide/basics/custom-conversions Shows how to apply #[builder(with)] within an impl block for a method setter. The `Example::example` method uses the attribute on its `point` parameter to define a custom conversion from two `u32` values to a `Point` struct. The `.call()` method is invoked on the builder. ```rust struct Point { x: u32, y: u32, } struct Example; #[bon::bon] impl Example { #[builder] fn example( #[builder(with = |x: u32, y: u32| Point { x, y })] point: Point, ) -> Point { point } } let value = Example::example() .point(2, 3) .call(); assert_eq!(value.x, 2); assert_eq!(value.y, 3); ``` -------------------------------- ### Automatic Into Conversions for Function Builders Source: https://bon-rs.com/guide/basics/into-conversions Demonstrates automatic `impl Into` setters for function-based builders using `#[bon::builder(on(Type, into))]` and `#[builder(into)]`. This simplifies the builder usage by allowing direct assignment of string literals and paths. ```rust use std::path::PathBuf; // All setters for members of type `String` will accept `impl Into` #[bon::builder(on(String, into))] fn example( name: String, description: String, // The setter only for this member will accept `impl Into` #[builder(into)] path: PathBuf, ) {} example() .name("Bon") .description("Awesome crate 🐱") .path("/path/to/your/heart") .call(); ``` -------------------------------- ### Shared Function Builder Configuration with macro_rules_attribute Source: https://bon-rs.com/guide/patterns/shared-configuration Applies shared builder configurations to functions using `attribute_alias` and `apply` from `macro_rules_attribute`. This pattern is useful for maintaining consistency in function builder setups across a crate. ```rust use macro_rules_attribute::{attribute_alias, apply}; attribute_alias! { #[apply(builder!)] = #[::bon::builder( on(String, into), on(Box<_>, into), finish_fn = finish, )]; } #[apply(builder!)] fn my_lovely_fn1(/**/) { /**/ } #[apply(builder!)] fn my_lovely_fn2(/**/) { /**/ } ``` -------------------------------- ### Switch Between Option and #[builder(default)] in Rust Source: https://bon-rs.com/guide/basics/compatibility Illustrates that switching a builder member between `Option` and `#[builder(default)]` is fully compatible. The builder API remains unchanged, allowing existing calls to continue working without modification. ```rust use bon::builder; #[builder] fn example(filter: Option) {} example().maybe_filter(Some("filter".to_owned())).call(); ``` This code can be changed to use `#[builder(default)]` and the call site will still compile: ```rust use bon::builder; #[builder] fn example( #[builder(default)] filter: Option filter: String ) {} example.maybe_filter(Some("filter".to_owned())).call(); ``` ``` -------------------------------- ### Impl Block with Default Members - Bon Builder Rust Source: https://bon-rs.com/guide/basics/optional-members Demonstrates using `#[bon::bon]` on an `impl` block to define a method 'example' with default arguments 'a' and 'b', similar to the function example. 'a' uses the `Default` trait, and 'b' defaults to 4. ```rust struct Example; #[bon::bon] impl Example { #[builder] fn example( // This uses the `Default` trait #[builder(default)] a: u32, // This uses the given custom default value #[builder(default = 4)] b: u32, ) -> u32 { a + b } } // Here, the default values will be used `a = 0` and `b = 4` let result = Example::example().call(); assert_eq!(result, 4); ``` -------------------------------- ### Automatic Into Conversions for Struct Builders Source: https://bon-rs.com/guide/basics/into-conversions Shows how to configure `#[builder(into)]` and `#[builder(on(Type, into))]` for struct builders to automatically accept `impl Into` for `String` and `PathBuf` members. This removes the need for manual `.to_owned()`, `.to_string()`, or `.into()` calls. ```rust use std::path::PathBuf; // All setters for members of type `String` will accept `impl Into` #[derive(bon::Builder)] #[builder(on(String, into))] struct Example { name: String, description: String, // The setter only for this member will accept `impl Into` #[builder(into)] path: PathBuf, } Example::builder() .name("Bon") .description("Awesome crate 🐱") .path("/path/to/your/heart") .build(); ``` -------------------------------- ### Rust: Custom Fallible Builder Finishing Function with `#[derive(Builder)]` Source: https://bon-rs.com/guide/patterns/fallible-builders This example shows how to implement a custom finishing function for a fallible builder when using `#[derive(Builder)]`. It overrides the default `build()` method to perform custom validation after the builder's internal state is constructed. The auto-generated finishing function is made private. Dependencies include `anyhow::Error` and `bon::Builder`. ```rust use anyhow::Error; use bon::Builder; #[derive(Builder)] // Ask `bon` to make the auto-generated finishing function private // and name it `build_internal()` instead of the default `build()` #[builder(finish_fn(vis = "", name = build_internal))] pub struct User { id: u32, name: String, } // Define a custom finishing function as a method on the `UserBuilder`. // The builder's state must implement the `IsComplete` trait. // See details about it in the tip below this example. impl UserBuilder { pub fn build(self) -> Result { // Delegate to `build_internal()` to get the instance of user. let user = self.build_internal(); // Now validate the user or do whatever else you want with it. if user.name.is_empty() { return Err(anyhow::anyhow!("Empty name is disallowed")); } Ok(user) } } let result: Result = User::builder() .id(42) .name(String::new()) .build(); ``` -------------------------------- ### Automatic Into Conversions for Method Builders Source: https://bon-rs.com/guide/basics/into-conversions Shows how to configure automatic `impl Into` setters for method builders within an `impl` block using `#[bon::bon]` and `#[builder(on(Type, into))]` with `#[builder(into)]`. This allows for cleaner builder calls by accepting various into-convertible types. ```rust use std::path::PathBuf; struct Example; #[bon::bon] impl Example { // All setters for members of type `String` will accept `impl Into` #[builder(on(String, into))] fn example( name: String, description: String, // The setter only for this member will accept `impl Into` #[builder(into)] path: PathBuf, ) {} } Example::example() .name("Bon") .description("Awesome crate 🐱") .path("/path/to/your/heart") .call(); ``` -------------------------------- ### Shared Struct Builder Configuration with macro_rules_attribute Source: https://bon-rs.com/guide/patterns/shared-configuration Solves code duplication by defining a shared configuration using `attribute_alias` from the `macro_rules_attribute` crate. This allows applying a consistent set of builder configurations to multiple structs efficiently. ```rust use macro_rules_attribute::{attribute_alias, apply}; attribute_alias! { #[apply(derive_builder!)] = #[derive(::bon::Builder)] #[builder( on(String, into), on(Box<_>, into), finish_fn = finish, )]; } #[apply(derive_builder!)] struct MyLovelyStruct1 { /**/ } #[apply(derive_builder!)] struct MyLovelyStruct2 { /**/ } ``` -------------------------------- ### Duplicate Builder Configuration in Rust Source: https://bon-rs.com/guide/patterns/shared-configuration Demonstrates the problem of repeating the same builder configuration for multiple structs. This approach leads to code duplication when needing to apply consistent settings like `Into` conversions or custom finishing function names across different builders. ```rust use bon::Builder; #[derive(Builder)] #[builder( on(String, into), on(Box<_>, into), finish_fn = finish, )] struct MyLovelyStruct1 { /**/ } #[derive(Builder)] #[builder( on(String, into), on(Box<_>, into), finish_fn = finish, )] struct MyLovelyStruct2 { /**/ } ``` -------------------------------- ### Using IsSet for Multiple Required Members in Rust Source: https://bon-rs.com/guide/typestate-api/custom-methods Illustrates how to define a function that accepts a closure for building a struct with multiple required members. It highlights the verbosity of using individual IsSet bounds for each member. ```rust use bon::Builder; #[derive(Builder)] struct ExampleParams { x1: u32, x2: u32, x3: Option, } // Our goal is to have this API example(|builder| builder.x1(1).x2(2)); // Below is how we could achieve this // Import traits from the generated module use example_params_builder::{State, IsSet}; fn example(f: impl FnOnce(ExampleParamsBuilder) -> ExampleParamsBuilder) where S: State, S::X1: IsSet, S::X2: IsSet, { let builder = f(ExampleParams::builder()); let params = builder.build(); } ``` -------------------------------- ### Rust: `Into` Conversion Setter Signature Change Source: https://bon-rs.com/guide/patterns/into-conversions-in-depth Shows the change in the setter method signature before and after enabling `impl Into` conversions, explaining why the compiler loses type information for `None`. This is a conceptual representation of the signature change. ```rust fn maybe_member(self, value: Option) -> ExampleBuilder> fn maybe_member(self, value: Option>) -> ExampleBuilder> ``` -------------------------------- ### Enabling Implied Bounds Feature in Cargo.toml Source: https://bon-rs.com/guide/typestate-api/custom-methods Shows how to enable the 'implied-bounds' feature for the 'bon' crate in a Cargo.toml file. This feature requires Rust 1.79.0 or later and increases the Minimum Supported Rust Version (MSRV). ```toml [dependencies] bon = { version = "3.8", features = ["implied-bounds"] } ``` -------------------------------- ### Accessing `#[builder(start_fn)]` Members in Bon RS Source: https://bon-rs.com/guide/typestate-api/builder-fields Shows how to access members marked with `#[builder(start_fn)]` directly by their name on the builder. These members are typically fields of the struct being built and are initialized when the builder is created. ```rust use bon::Builder; #[derive(Builder)] struct Example { #[builder(start_fn)] x1: u32 } let builder = Example::builder(99); // We can access the `x1` on the builder directly. let x1: u32 = builder.x1; assert_eq!(x1, 99); ``` -------------------------------- ### Rust: Workaround for `None` Inference with Explicit Type Source: https://bon-rs.com/guide/patterns/into-conversions-in-depth Provides the solution to the `None` literal inference problem by explicitly specifying the generic type for `Option` when passing `None` to the setter. This code requires the `bon` crate. ```rust use bon::Builder; #[derive(Builder)] struct Example { #[builder(into)] member: Option } Example::builder() .maybe_member(None::) .build(); ``` -------------------------------- ### Rust: Default Builder Syntax Without `impl Into` Conversions Source: https://bon-rs.com/guide/patterns/into-conversions-in-depth Shows the equivalent builder usage without `impl Into` conversions enabled. This requires explicit manual conversions (e.g., `.to_owned()`, `.into()`) for literals, resulting in more verbose code compared to using `into` attributes. ```rust use bon::Builder; #[derive(Builder)] struct Example { // No attributes string: String, // No attributes path_buf: std::path::PathBuf, // No attributes ip_addr: std::net::IpAddr, } Example::builder() // We have to convert `&str -> String` manually .string("string literal".to_owned()) // We have to convert `&str -> PathBuf` manually .path_buf("string/literal".into()) // We have to convert `[u8; 4] -> IpAddr` manually .ip_addr([127, 0, 0, 1].into()) .build(); ``` -------------------------------- ### Derive Debug for Method Builder - Rust Source: https://bon-rs.com/guide/basics/derives-for-builders Adds the `Debug` derive to a builder generated for an implementation method. This allows debugging the builder's state before invoking the method. It processes method arguments to create a debuggable builder. ```rust struct Example; #[bon::bon] impl Example { #[builder(derive(Debug))] fn method( name: String, is_admin: bool, level: Option, ) {} } let builder = Example::method().name("Bon".to_owned()); // This will output the current state of the builder to `stderr` dbg!(&builder); // You can also format the debug output to `String`: assert_eq!( format!("{builder:?}"), // Only the fields that were set will be output r#"ExampleMethodBuilder { name: \"Bon\" }"# ); // Finish building builder.is_admin(true).call(); ``` -------------------------------- ### Function with Default Arguments - Bon Builder Rust Source: https://bon-rs.com/guide/basics/optional-members Creates a Rust function 'example' with optional arguments 'a' and 'b' using `#[builder(default)]`. 'a' defaults to its `Default` trait implementation, and 'b' defaults to 4. The function returns the sum of 'a' and 'b'. ```rust #[bon::builder] fn example( // This uses the `Default` trait #[builder(default)] a: u32, // This uses the given custom default value #[builder(default = 4)] b: u32, ) -> u32 { a + b } // Here, the default values will be used `a = 0` and `b = 4` let result = example().call(); assert_eq!(result, 4); ``` -------------------------------- ### Mark Member Unused with Leading Underscore in Rust Builders Source: https://bon-rs.com/guide/basics/compatibility Shows how prefixing a member name with `_` marks it as unused temporarily without altering the builder API. The leading underscore is automatically removed, and the setter retains its original name. ```rust use bon::Builder; #[derive(Builder)] struct Example { _name: String } Example::builder() .name("The setter is still called `name`".to_owned()) .build(); ``` ```rust use bon::builder; #[builder] fn example( _name: String ) {} example() .name("The setter is still called `name`".to_owned()) .call(); ``` ```rust use bon::{bon, builder}; struct Example; #[bon] impl Example { #[builder] fn example(_name: String) {} } Example::example() .name("The setter is still called `name`".to_owned()) .call(); ``` ``` -------------------------------- ### Struct Field Setter with Custom Conversion - Rust Source: https://bon-rs.com/guide/basics/custom-conversions Demonstrates using #[builder(with)] on a struct field to provide a custom conversion logic. The setter accepts multiple arguments (u32, u32) and constructs a 'Point' struct. This is useful when a simple `Into` conversion is insufficient. ```rust struct Point { x: u32, y: u32, } #[derive(bon::Builder)] struct Example { #[builder(with = |x: u32, y: u32| Point { x, y })] point: Point, } let value = Example::builder() .point(2, 3) .build(); assert_eq!(value.point.x, 2); assert_eq!(value.point.y, 3); ``` -------------------------------- ### Rust: `None` Literal Without `Into` Conversion Source: https://bon-rs.com/guide/patterns/into-conversions-in-depth Demonstrates a scenario where `None` literals are used without `impl Into` conversions, showing that type inference works correctly. This code requires the `bon` crate for the `Builder` derive macro. ```rust use bon::Builder; #[derive(Builder)] struct Example { member: Option } Example::builder() // Suppose we want to be explicit about omitting the `member`, // so we intentionally invoke the `maybe_` setter and pass `None` to it .maybe_member(None) .build(); ``` -------------------------------- ### Rust: Function Setter Validation with `#[builder(with)]` Source: https://bon-rs.com/guide/patterns/fallible-builders This Rust code demonstrates fallible setters for a function-based builder using the `#[builder]` attribute. The `x1` parameter is validated upon setting by parsing a string into a `u32`, with `ParseIntError` being the potential error. ```rust use bon::builder; use std::num::ParseIntError; #[builder] fn example( #[builder(with = |string: &str| -> Result<_, ParseIntError> { string.parse() })] x1: u32, ) -> u32 { x1 } fn main() -> Result<(), ParseIntError> { example() .x1("99")? // <-- the setter returns a `Result` .call(); Ok(()) } ``` -------------------------------- ### Finishing Function: Move Members to Parameters (Function, Rust) Source: https://bon-rs.com/guide/basics/positional-members Illustrates using `#[builder(finish_fn)]` on a standalone function to move members to its parameters. This enables passing specific arguments directly to the function that concludes the builder process. Uses the `bon::builder` attribute. ```rust // Top-level attribute to give a custom name for the finishing function #[bon::builder(finish_fn = located_at)] fn 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 { format!("{x}, {y}, {label:?}") } let treasure = treasure() .label("oats".to_owned()) .located_at(2, 9); assert_eq!(treasure, r###"2, 9, Some("oats")"###); ``` -------------------------------- ### Finishing Function: Move Members to Parameters (Struct, Rust) Source: https://bon-rs.com/guide/basics/positional-members Demonstrates using `#[builder(finish_fn)]` on a struct to move members to the parameters of a custom-named finishing function. This allows specific fields to be passed directly when the build process is completed. Requires `bon::Builder` derive. ```rust #[derive(bon::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, } 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")); ``` -------------------------------- ### Rust Collection Initialization with bon::vec! Macro Source: https://bon-rs.com/guide/alternatives Shows how to initialize a `Vec` using `bon`'s `vec!` macro, which supports `Into` conversions for its elements. This provides a concise way to populate collections, especially when types need conversion. ```rust use bon::Builder; #[derive(Builder)] struct User { friends: Vec } User::builder() .friends(bon::vec![ "Foo", "Bar", "`String` value is also accepted".to_owned(), ]) .build(); ``` -------------------------------- ### Documenting Function Arguments with Bon Builder (Rust) Source: https://bon-rs.com/guide/basics/documenting Demonstrates how documentation comments on function arguments are automatically moved to the generated setter methods by the `#[bon::builder]` macro. This allows for clear documentation of each parameter's purpose and usage within the builder pattern. ```rust /// Function that returns a greeting special-tailored for a given person #[bon::builder] fn greet( /// Name of the person to greet. /// /// **Example:** /// ``` /// greet().name("John"); /// ``` name: &str, /// Age expressed in full years passed since the birth date. age: u32 ) -> String { format!("Hello {name} with age {age}!") } ``` -------------------------------- ### Builder and State Module Visibility in Bon RS Source: https://bon-rs.com/guide/typestate-api/builders-type-signature Illustrates the default visibility of a generated builder type and its associated state module. The builder type inherits visibility from the original struct, while the state module is private by default. This example assumes a `#[derive(bon::Builder)]` on a `pub struct Example`. ```rust // Let's suppose we had this derive on a struct with `pub` visibility // #[derive(bon::Builder)] pub struct Example { x1: u32 } // Builder type inherits the `pub` visibility from the underlying `Example` struct // from which it was generated. pub struct ExampleBuilder { /**/ } // Typestate module is private by default. It means it is accessible only within // the surrounding module. mod example_builder { // The type states inherit the builder type's visibility, which is `pub` pub struct SetX1 { /**/ } pub struct Empty { /**/ } // ... } ``` -------------------------------- ### Generate Getter with Bon RS (Rust) Source: https://bon-rs.com/guide/typestate-api/getters Generates a getter method for a struct member using the `#[builder(getter)]` attribute. The getter is only available if the member's value has been set, indicated by the `IsSet` trait. This example shows a basic getter generation. ```rust use bon::Builder; #[derive(Builder)] struct Example { #[builder(getter)] x: u32 } // Assuming ExampleBuilder is generated by bon::Builder // and that S::X implements IsSet when the value is set. // let builder = Example::builder().x(3); // assert_eq!(builder.get_x(), 3); ``` -------------------------------- ### Rust Function-Based Builder with bon::bon Source: https://bon-rs.com/guide/alternatives Demonstrates creating a builder for a struct using the `bon::bon` macro on an impl block. This approach decouples the builder's internal representation from the struct itself. The generated builder allows setting fields and calling `build()`. ```rust use bon::bon; pub struct Line { point1: Point, point2: Point, } struct Point { x: u32, y: u32, } #[bon] impl Line { #[builder] fn new(x1: u32, y1: u32, x2: u32, y2: u32) -> Self { Self { point1: Point { x: x1, y: y1 } , point2: Point { x: x2, y: y2 } , } } } // Example usage: // Line::builder().x1(1).y1(2).x2(3).y2(4).build(); ``` -------------------------------- ### Rust: Switch from `#[derive(Builder)]` to `#[builder]` on `new()` Source: https://bon-rs.com/guide/basics/compatibility Demonstrates how to migrate from using `#[derive(Builder)]` on a struct to using `#[builder]` on a `new()` method. This allows for custom construction logic while preserving the original builder API compatibility, ensuring that callers can still use the builder with the original parameter types. ```rust use bon::Builder; use bon::bon; // Previously we used `#[derive(Builder)]` on the struct #[derive(Builder)] struct User { // But then we decided to change the internal representation // of the `id` field to use `String` instead of `u32` id: u32, id: String, name: String, } // To preserve compatibility we need to define a `new()` method with `#[builder]` // that still accepts `u32` for the `id` member. #[bon] impl User { #[builder] fn new(id: u32, name: String) -> Self { Self { id: format!("u-{id}"), name, } } } // The caller's code didn't change. It still uses `u32` for the `id` member. let user = User::builder() // `id` is still accepted as a `u32` here .id(1) .name("Bon".to_owned()) .build(); ``` -------------------------------- ### Generated Setter for Builder Field Source: https://bon-rs.com/guide/typestate-api/custom-methods This Rust code illustrates a generated setter method for a builder. It assumes the 'Example' struct from the previous snippet and shows how the 'x1' field is made mutable. The setter `x1` takes a u32 value and returns a new builder instance with an updated type state, constrained by the `IsUnset` trait to ensure valid transitions. ```rust // Import traits and type states from the generated module use example_builder::{State, IsUnset, SetX1}; impl ExampleBuilder { fn x1(self, value: u32) -> ExampleBuilder> where S::X1: IsUnset { /* */ } } ``` -------------------------------- ### Customizing Builder Documentation with `doc` Attributes (Rust) Source: https://bon-rs.com/guide/basics/documenting Shows how to use the `doc` attribute within `#[derive(bon::Builder)]` and `#[bon::builder]` macros to provide custom documentation for the generated builder struct, finishing function, and other builder components. This allows for fine-grained control over the generated documentation. ```rust #[derive(bon::Builder)] #[builder( builder_type(doc { /// Custom docs on the builder struct itself }), finish_fn(doc { /// Custom docs on the finishing function }), // ... )] struct Example {} ``` ```rust #[bon::builder( builder_type(doc { /// Custom docs on the builder struct itself }), finish_fn(doc { /// Custom docs on the finishing function }), // ... )] fn example() {} ``` ```rust struct Example; #[bon::bon] impl Example { #[builder( builder_type(doc { /// Custom docs on the builder struct itself }), finish_fn(doc { /// Custom docs on the finishing function }), // ... )] fn example() {} } ``` -------------------------------- ### Rust: Struct Builder with Derive macro Source: https://bon-rs.com/guide/alternatives Demonstrates using the `#[derive(Builder)]` macro from the 'bon' crate to automatically generate a builder for a Rust struct. This is the conventional approach for creating builders. ```rust use bon::Builder; #[derive(Builder)] pub struct Line { x1: u32, y1: u32, x2: u32, y2: u32, } // Example usage: // Line::builder().x1(1).y1(2).x2(3).y2(4).build(); ``` -------------------------------- ### Add Bon dependency to Cargo.toml Source: https://bon-rs.com/guide/overview Specifies how to add the 'bon' crate as a dependency in a Rust project's `Cargo.toml` file. It shows the basic `[dependencies]` entry and mentions the possibility of opting out of `std` and `alloc` features for `no_std` environments. ```toml [dependencies] bon = "3.8" ``` -------------------------------- ### Derive Debug for Function Builder - Rust Source: https://bon-rs.com/guide/basics/derives-for-builders Adds the `Debug` derive to a builder generated for a function. This is useful for debugging the state of the builder before calling the function. It takes function arguments and generates a builder with debug capabilities. ```rust #[bon::builder(derive(Debug))] fn example( name: String, is_admin: bool, level: Option, ) {} let builder = example().name("Bon".to_owned()); // This will output the current state of the builder to `stderr` dbg!(&builder); // You can also format the debug output to `String`: assert_eq!( format!("{builder:?}"), // Only the fields that were set will be output r#"ExampleBuilder { name: \"Bon\" }"# ); // Finish building builder.is_admin(true).call(); ``` -------------------------------- ### Define Builder with Typestate using Bon RS Source: https://bon-rs.com/guide/typestate-api/builders-type-signature Demonstrates defining a struct with the `#[derive(Builder)]` macro and then constructing an instance using the generated builder, showcasing type state transitions. It requires importing the `Builder` trait and the generated type states. ```rust use bon::Builder; #[derive(Builder)] struct Example { x1: u32, x2: u32, } // Import type states from the generated module use example_builder::{SetX1, SetX2}; let builder: ExampleBuilder = Example::builder(); let builder: ExampleBuilder = builder.x1(1); let builder: ExampleBuilder> = builder.x2(2); ``` -------------------------------- ### Generate Method Builder with #[bon] and #[builder] Source: https://bon-rs.com/guide/overview Enables builder generation for methods within an `impl` block by annotating the block with `#[bon]` and individual methods with `#[builder]`. The `new` method generates `builder()` and `build()` methods, while other methods generate `{method_name}()` and `call()` methods for fluent invocation. ```rust use bon::bon; struct User { id: u32, name: String, } #[bon] impl User { #[builder] fn new(id: u32, name: String) -> Self { Self { id, name } } } let user = User::builder() .id(1) .name("Bon".to_owned()) .build(); assert_eq!(user.id, 1); assert_eq!(user.name, "Bon"); ``` ```rust use bon::bon; struct Greeter { name: String, } #[bon] impl Greeter { #[builder] fn greet(&self, target: &str, prefix: Option<&str>) -> String { let prefix = prefix.unwrap_or("INFO"); let name = &self.name; format!("[{prefix}] {name} says hello to {target}") } } let greeter = Greeter { name: "Bon".to_owned() }; let greeting = greeter .greet() .target("the world") // `prefix` is optional, omitting it is fine .call(); assert_eq!(greeting, "[INFO] Bon says hello to the world"); ``` -------------------------------- ### Avoid `impl Into` for Performance-Sensitive Allocations in Rust Source: https://bon-rs.com/guide/patterns/into-conversions-in-depth Demonstrates how using `impl Into` with `#[builder]` can lead to unintended data cloning when a reference is passed instead of moving ownership. This is crucial for performance-sensitive code where allocations are a bottleneck. ```rust use bon::builder; #[builder] fn process_heavy_json(#[builder(into)] data: String) { /* */ } let json = String::from( r#"{ \"key\": \"Pretend this is a huge JSON string with hundreds of MB in size\" }"#.strip_margin() ); process_heavy_json() // Whoops, we passed a `&String`. // The builder will clone the data internally. .data(&json) .call(); ``` -------------------------------- ### Rust: Create Fallible Builder with `#[bon]` Constructor Source: https://bon-rs.com/guide/patterns/fallible-builders This snippet demonstrates how to create a fallible builder using the `#[bon]` attribute on a constructor function that returns a `Result`. Input validation is performed within the constructor, and the generated `build()` method of the builder returns this `Result`. Dependencies include `anyhow::Error` for error handling and `bon::bon` for deriving the builder. ```rust use anyhow::Error; use bon::bon; pub struct User { id: u32, name: String, } #[bon] impl User { #[builder] pub fn new(id: u32, name: String) -> Result { if name.is_empty() { return Err(anyhow::anyhow!("Empty name is disallowed")); } Ok(Self { id, name }) } } // The `build()` method returns a `Result` let result = User::builder() .id(42) .name(String::new()) .build(); if let Err(error) = result { // Handle the error } ``` -------------------------------- ### Generate Struct Builder with #[derive(Builder)] Source: https://bon-rs.com/guide/overview Automatically generates a builder for a struct using the `#[derive(Builder)]` macro. This simplifies the instantiation of complex structs by providing a fluent API for setting fields, including optional ones. Setters can be called in any order, and the `build()` method constructs the final struct instance. ```rust use bon::Builder; #[derive(Builder)] struct User { name: String, is_admin: bool, level: Option, } let user = User::builder() .name("Bon".to_owned()) // `level` is optional, we could omit it here .level(24) // call setters in any order .is_admin(true) .build(); assert_eq!(user.name, "Bon"); assert_eq!(user.level, Some(24)); assert!(user.is_admin); ``` -------------------------------- ### Deriving Builder with IsSet Trait in Rust Source: https://bon-rs.com/guide/typestate-api/custom-methods Demonstrates how to derive the Builder pattern for a struct with a required and an optional member using Rust. The generated code allows for type-safe checks using the IsSet trait on finishing methods. ```rust use bon::Builder; #[derive(Builder)] struct Example { x1: u32, x2: Option, } ``` ```rust use example_builder::{State, IsSet}; impl ExampleBuilder { fn build(self) -> Example where S::X1: IsSet, { /**/ } } ``` -------------------------------- ### Rust: Using `impl Into` for Shorter Literal Syntax with Builder Source: https://bon-rs.com/guide/patterns/into-conversions-in-depth Demonstrates how to use `#[builder(into)]` to allow passing literals directly to builder fields. The `bon::Builder` derive macro automatically handles conversions for types like `String`, `PathBuf`, and `IpAddr` when `Into` is enabled, reducing caller boilerplate. ```rust use bon::Builder; #[derive(Builder)] struct Example { #[builder(into)] string: String, #[builder(into)] path_buf: std::path::PathBuf, #[builder(into)] ip_addr: std::net::IpAddr, } Example::builder() // We can pass `&str` literal .string("string literal") // We can pass `&str` literal or a String .path_buf("string/literal") // We can pass an array of IP components or `Ipv4Addr` or `Ipv6Addr` .ip_addr([127, 0, 0, 1]) .build(); ```