#[derive(Builder)]
{
// Attributes available to this derive:
#[builder]
}
Expand description
The main macro
§Usage
#[derive(Builder)]
pub struct Foo {
#[builder(default = "42")]
pub field_a: u32,
pub field_b: bool,
#[builder(into)]
pub field_c: String,
#[builder(repeat, repeat_n = 1..=3)]
pub field_d: Vec<f64>,
}§Errors
When a builder can fail, the .build() function will return a Result that contains the
built value or an error for the problem. The current errors are:
Missing{Field}- A required field is missingRange{Field}(usize)- A field was not specified with the correct number of arguments. The specified quantity is in the enum.
Where {Field} is replaced with the PascalCase version of the field name.
§Type-State Builder
If the builder kind is "type-state", then all errors will be presented as type-errors at
compile-time and the .build() function will not return a Result. (unless
error(force) is set).
§Forcing Results
If you wish to force the generated .build() function to always return a Result, add the
error(force) attribute to the builder.
§Builder Attributes
§kind
§"owned" (default)
All builder functions accept self and return Self.
#[derive(Builder)]
#[builder(kind = "owned")]
pub struct Foo {
a: u32,
}
let foo: Foo = Foo::builder()
.a(42)
.build()?;§"borrowed"
All builder functions accept &mut self and return &mut Self.
This pattern is ideal for builders that need to be dynamic because passing it to functions and using it it loops tends to be more ergonomic.
Note: After calling .build(), the builder is reset
#[derive(Builder)]
#[builder(kind = "borrowed")]
pub struct Foo {
#[builder(repeat)]
values: Vec<u32>,
}
let mut builder = Foo::builder();
for x in 0..3 {
builder.values(x);
}
let foo: Foo = builder.build();
assert_eq!(foo.values, [0, 1, 2]);§"type-state"
The builder and its functions are generated in a way that uses the type-state pattern. This means that things like required fields can be enforced at compile-time and will refuse to compile if required fields are not set correctly.
The .build() function will never return an error since erroneous calls will fail to compile.
This can make error messages harder to decode, but it does provide a static guarantee that the builder was used correctly at compile-time.
#[derive(Builder)]
#[builder(kind = "type-state")]
pub struct Foo {
a: u32,
}
let foo: Foo = Foo::builder().build(); // fails to compile because `a` is missing§const
Make the generated builder work at compile-time.
Using const creates some limitations for the builder, primarily:
- All types need to be constructable at compile-time
repeatonly works on arrays (repeat_nis disabled)adapters must be const (no syntax change needed, but the body needs to work in const)intois disableddefaultrequires the default value to be specified and be const (default = "<expression>")
const works best with type-state builders since their .build() function can’t fail, but it
does work with all builders, error handling just takes more thought.
#[derive(Builder)]
#[builder(kind = "type-state", const)]
pub struct Foo {
a: u32,
}
const FOO: Foo = Foo::builder()
.a(42)
.build();§prefix/suffix
Default: prefix = "", suffix = ""
Set the prefix or suffix for the generated builder functions
#[derive(Builder)]
#[builder(prefix = "set_")]
pub struct Foo {
a: u32,
}
let f = Foo::builder()
.set_a(42)
.build()?;§visibility
Default: visibility of the struct
Set the visibility for the generated builder struct
The visibility can be set to pub(self) in order to make the builder private to the current
module.
#[derive(Builder)]
#[builder(visibility = pub(crate))]
pub struct Foo {
a: u32,
}§crate
Default: bauer
The name of this crate in the current crate. This should only need to be changed if you rename
the dependency in your Cargo.toml
#[derive(Builder)]
#[builder(crate = not_bauer)]
pub struct Foo {
a: u32,
}§attributes
Any attributes specified in attributes will be added to the generated builder for this field.
You may also use attribute instead of attributes.
The contents may be wrapped with either () or {} and attributes may optionally be separated
using commas.
#[derive(Builder)]
#[builder(
attributes(
#[my_attribute]
#[my_attribute2]
),
)]
pub struct Foo {
field: u32,
}§doc
Add documentation to the generated builder struct or the generated .build() function
#[doc] attributes may also be added using this attribute, i.e., doc(hidden).
The contents may be wrapped with either () or {} and attributes may optionally be separated
using commas.
#[derive(Builder)]
#[builder(
doc {
/// Some documentation for my field
},
)]
pub struct Foo {
field: u32,
}§build_fn
Specify details surrounding the generated .build() function on the builder. There are a few
attributes that may be specified here:
attributes- Specify attributes to be applied to the build function (seeattributes)doc- Add documentation to the generated build function (seedoc)rename = <name>- Rename the build function from the default ofbuild
The contents may be wrapped with either () or {} and attributes may optionally be separated
using commas.
#[derive(Builder)]
#[builder(
build_fn {
attributes {
#[my_attribute]
#[my_attribute2]
},
doc {
/// Some documentation about the build function
},
rename = "finish",
},
)]
pub struct Foo {
field: u32,
}
let foo: Foo = Foo::builder()
.field(3)
.finish()?;§builder_fn
Specify details surrounding the generated .builder() function on the struct. There are a few
attributes that may be specified here:
attributes- Specify attributes to be applied to the build function (seeattributes)doc- Add documentation to the generated build function (seedoc)rename = <name>- Rename the build function from the default ofbuild
The contents may be wrapped with either () or {} and attributes may optionally be separated
using commas.
#[derive(Builder)]
#[builder(
builder_fn {
attributes {
#[my_attribute]
#[my_attribute2]
},
doc {
/// Some documentation about the builder function
},
rename = "renamed_function",
},
)]
pub struct Foo {
field: u32,
}
let foo: Foo = Foo::renamed_function()
.field(3)
.build()?;§error
Specify details surrounding the generated error type for the builder. There are a few attributes that may be specified here:
attributes- Specify attributes to be applied to error enum (seeattributes) [This field is ignored on Type-State builders]doc- Add documentation to the generated error enum (seedoc) [This field is ignored on Type-State builders]rename = <name>- Rename the error enum from the default{struct}BuildError[This field is ignored on Type-State builders]force- Force the builder to return an error. This is the error enum for Owned and Borrowed builders, andInfallibleon Type-State.
The contents may be wrapped with either () or {} and attributes may optionally be separated
using commas.
#[derive(Builder)]
#[builder(
error {
attributes {
#[my_attribute]
#[my_attribute2]
},
doc {
/// Some documentation about the build function
},
rename = "FooBuildFailure",
},
)]
pub struct Foo {
field: u32,
}
let result: Result<Foo, FooBuildFailure> = Foo::builder()
.field(3)
.build();§on
Specify a set of field attributes that should be applied to all fields that match a specific type.
Type matching is done by specifying a pattern that may contain _ to represent a wildcard type.
When a wildcard is matched, the result of the match is can be used in the attributes as
#<index> (i.e., #0). Due to parsing reasons, a wildcard after dyn needs to be specified
with __.
§NOTE
Due to how derive macros work, this type matching happens on the level of tokens. So,
Vec<_>does not matchstd::vec::Vec<T>. This limitation applies to all parts of the type, including generics, constants, etc.
#[derive(Builder)]
#[builder(on(Vec<_> => repeat))]
pub struct Foo {
field: Vec<u32>,
}
let result: Foo = Foo::builder()
.field(0)
.field(1)
.field(2)
.build();#[derive(Builder)]
#[builder(on(HashMap<_, _> => repeat = (#0, #1), tuple))]
pub struct Foo {
#[builder(into)]
bar: HashMap<String, f64>,
baz: HashMap<u32, f64>,
}
let result: Foo = Foo::builder()
.bar("pi", 3.14)
.bar("tau", 6.28)
.baz(0, 1.0)
.baz(5, 63.4)
.build();§Fields Attributes
§skip
Argument: Optional Expression
Prevent a field from being in the builder. If provided with no expression, the value will be
created from Default. The expression provided may access the values of all other fields
that are not skipped. These can be accessed like variables using the name of the field.
#[derive(Builder)]
pub struct Foo {
#[builder(skip)]
a: u32,
#[builder(skip = *c as f32)] // uses field `c`
b: f32,
c: u32,
}
let foo = Foo::builder()
.c(42)
.build()?;
assert_eq!(foo.a, 0);
assert_eq!(foo.b, 42.0);
assert_eq!(foo.c, 42);§default
Argument: Optional String
If no default value is provided, the field will attempt to be set using the Default trait.
Otherwise, the passed string will be parsed as an expression and used to set the default (only
run when .build() is called and no value has been set)
#[derive(Builder)]
pub struct Foo {
#[builder(default)]
a: u32, // defaults to 0
#[builder(default = "std::f32::consts::PI")]
b: f32, // defaults to PI
}
let foo = Foo::builder().build();
assert_eq!(foo.a, 0);
assert_eq!(foo.b, std::f32::consts::PI);
let foo = Foo::builder()
.a(42)
.build();
assert_eq!(foo.a, 42);
assert_eq!(foo.b, std::f32::consts::PI);§repeat
Make the generated method consume the “inner type” and build the field type at the end. By
default it uses FromIterator to build the final type, but that may be overridden with the
collector attribute.
If the field type has a single generic parameter, then that generic will be chosen as the inner
type. If the field has a different number of generics, or if the inner type needs to be
different, then the type may be set with repeat = <inner type>.
#[derive(Builder)]
pub struct Foo {
#[builder(repeat)]
items: Vec<u32>,
#[builder(repeat = char)]
chars: String,
}
let foo = Foo::builder()
.items(0)
.items(1)
.items(2)
.chars('a')
.chars('b')
.chars('c')
.build();
assert_eq!(foo.items, [0, 1, 2]);
assert_eq!(foo.chars, "abc");§repeat_n
Ensure that the length of items supplied via repeat is within a certain range.
The repeat must be specified before repeat_n.
For Owned and Borrowed builders, the range may be any statement that belongs on the left side
of a match statement. For Type-State builders, the usage is limited to integers (N), closed
ranges (N..M or N..=M), and lower-bounded ranges (N..). The length of a range is limited
to 64 in order to protect against very slow compile-time. If a larger range is required, the
unlimited_range feature may be enabled.
#[derive(Debug, Builder)]
pub struct Foo {
#[builder(repeat, repeat_n = 2..=3)]
items: Vec<u32>,
}
let foo = Foo::builder().items(0).items(1).items(2).build();
assert!(foo.is_ok());
let foo = Foo::builder().items(0).build().unwrap_err();
assert_eq!(foo, FooBuildError::RangeItems(1));§rename
Change the name of the generated function from the default value matching the field name.
Note: This still applies the prefix/suffix. To skip those use skip_prefix/skip_suffix
#[derive(Builder)]
pub struct Foo {
#[builder(repeat, rename = "item")]
items: Vec<u32>,
}
let foo = Foo::builder()
.item(0)
.item(1)
.build();
assert_eq!(foo.items, [0, 1]);§skip_prefix/skip_suffix
If a prefix or suffix was set in the builder attributes, skip applying those for this
field. This is especially useful in combination with rename.
#[derive(Builder)]
#[builder(prefix = "set_")]
pub struct Foo {
#[builder(repeat, rename = "item", skip_prefix)]
items: Vec<u32>,
}
let foo = Foo::builder()
.item(0)
.item(1)
.build();
assert_eq!(foo.items, [0, 1]);§into
Make the generated function accept impl Into<FieldType>. This requires the field type
to implement From on whatever value is passed in.
#[derive(Builder)]
pub struct Foo {
#[builder(into)]
a: String,
}
let foo = Foo::builder()
.a("hello")
.build()?;
assert_eq!(foo.a, "hello");§tuple
Make generated function accept each item of the tuple as a separate parameters to the function.
By default, the names of the parameters are just field_0, field_1, etc. However, if names
are specified using tuple(name1, name2, ...), they will be used for the names of the
parameters to the function.
Note: If used with repeat, tuple must come after.
#[derive(Builder)]
pub struct Foo {
#[builder(tuple)]
tuple: (i32, i32),
#[builder(tuple(a, b))]
tuple_names: (i32, i32),
#[builder(into, tuple(a, b))]
tuple_into: (String, f64),
#[builder(repeat, tuple(foo, bar))]
tuples: Vec<(i32, i32)>,
}
let foo = Foo::builder()
.tuple(0, 1)
.tuple_names(2, 3)
.tuple_into("pi", 3.14)
.tuples(4, 5)
.tuples(6, 7)
.build();§adapter
Create a custom implementation for converting from arguments to a value.
An adapter uses the closure syntax where all arguments have their type specified. The body of the closure will then be used to generate the value. Multiple parameters may be used and their names and types will appear in the generated signature.
Conflicts with into and tuple.
#[derive(Builder)]
pub struct Foo {
#[builder(adapter = |x: u32, y: u32| format!("x={}, y={}", x, y))]
point: String,
}
let foo = Foo::builder()
.point(5, 23)
.build()?;
assert_eq!(foo.point, "x=5, y=23");§collector
On fields that use repeat, a collector may be specified to use in place of the default
FromIterator in order to collect the added values differently.
The value passed to a collector must be a function with the following signature:
fn my_collector(iter: impl ExactSizeIterator<Item = RepeatType>) -> FieldTypeWhere RepeatType is the type determined by the repeat attribute and FieldType is the type
of the field.
Note: Because Iterator is a super-trait of ExactSizeIterator, it may be used instead.
fn sum_collector(iter: impl Iterator<Item = u64>) -> u64 {
iter.sum()
}
#[derive(Builder)]
pub struct Foo {
#[builder(repeat = u64, collector = sum_collector)]
sum: u64,
}
let foo = Foo::builder()
.sum(21)
.sum(34)
.sum(55)
.build();
assert_eq!(foo.sum, 21 + 34 + 55);§attributes
Any attributes specified in attributes will be added to the generated function for this
field. You may also use attribute instead of attributes.
The contents may be wrapped with either () or {} and attributes may optionally be separated
using commas.
#[derive(Builder)]
pub struct Foo {
#[builder(
attributes(
#[my_attribute]
#[my_attribute2]
),
)]
field: u32,
}§doc
Add documentation to the generated function for this field.
#[doc] attributes may also be added using this attribute, i.e., doc(hidden).
The contents may be wrapped with either () or {} and attributes may optionally be separated
using commas.
#[derive(Builder)]
pub struct Foo {
#[builder(
doc {
/// Some documentation for my field
},
)]
field_a: u32,
#[builder(default, doc(hidden))]
field_b: u32,
}