Attribute Macro staged_builder::staged_builder
source · #[staged_builder]
Expand description
Creates a staged builder interface for structs.
The macro will create a submodule with the snake_case
version of the type’s name containing the builder types, and
add a builder
constructor function to the type. Each required field of the struct will correspond to a builder
type named after it, with an additional “final” stage to set optional fields and construct the final value.
By default, all fields are considered required and their setters will simply take their declared type by-value. This behavior can be customized with field options.
§Struct options
Options can be applied at the struct level via the #[builder(...)]
attribute as a comma-separated sequence:
validate
- The finalbuild
method will return aResult
, calling the type’sValidate
implementation before returning the constructed value.update
- The completed stage of the builder will have setters for all fields, and aFrom
impl will be created to allow an instance of the struct to be converted back into the builder type for further updates.crate
- Indicates the path to thestaged_builder
crate root. Useful when reexporting the macro from another crate. Defaults to::staged_builder
.mod
- The name of the submodule that will contain the generated builder types. Defaults to the struct’s name converted tosnake_case
.inline
- Causes the generated builder types to be defined in the same module as the struct, rather than a submodule.builder
- Sets the name of the generated builder type. Defaults toBuilder
.complete
- Sets the name of the generated complete stage type. Defaults toComplete
.
§Field options
Options can be applied to individual fields via the #[builder(...)]
attribute as a comma-separated sequence:
default
- Causes the field to be considered optional. The [Default
] trait is normally used to generate the default field value. A custom default can be specified withdefault = <expr>
, where<expr>
is an expression.into
- Causes the setter method for the field to takeimpl Into<FieldType>
rather thanFieldType
directly.custom
- Causes the setter method to perform an arbitrary conversion for the field. The option expects atype
which will be used as the argument type in the setter, and aconvert
callable expression which will be invoked by the setter. For example, the annotation#[builder(into)]
on a field of typeT
is equivalent to the annotation#[builder(custom(type = impl Into<T>, convert = Into::into))]
.list
- Causes the field to be treated as a “list style” type. It will default to an empty collection, and three setter methods will be generated:push_foo
to add a single value,foo
to set the contents, andextend_foo
to exend the collection with new values. The underlying type must have apush
method, a [FromIterator
] implementation, and an [Extend
] implementation. The item type must be configured in the attribute:#[builder(list(item(type = YourItemType)))]
.set
- Causes the field to be treated as a “set style” type. It will default to an empty collection, and three setter methods will be generated:insert_foo
to add a single value,foo
to set the contents, andextend_foo
to exend the collection with new values. The underlying type must have aninsert
method, a [FromIterator
] implementation, and an [Extend
] implementation. The item type must be configured in the attribute:#[builder(set(item(type = YourItemType)))]
.map
- Causes the field to be treated as a “map style” type. It will default to an empty collection, and three setter methods will be generated:insert_foo
to add a single entry,foo
to set the contents, andextend_foo
to exend the collection with new entries. The underlying type must have aninsert
method, a [FromIterator
] implementation, and an [Extend
] implementation. The key and value types must be configured in the attribute:#[builder(map(key(type = YourKeyType), value(type = YourValueType)))]
.stage
- Sets the name of the generated stage type. Defaults to the name of the field converted toPascalCase
withStage
appended.
§Collection type options
Options can be applied to the item types of collections as a comma-separated sequence:
type
- Indicates the type of the item in the collection. Required unless usingcustom
.into
- Causes setter methods to takeimpl<Into<ItemType>>
rather thanItemType
directly.custom
- Causes the setter methods to perform an arbitrary conversion for the field.
§Example expansion
use staged_builder::staged_builder;
#[staged_builder]
pub struct MyStruct {
required_field: u32,
#[builder(into)]
into_required_field: String,
#[builder(default)]
standard_optional_field: bool,
#[builder(default = "foobar".to_string())]
custom_default_field: String,
#[builder(list(item(type = i32)))]
list_field: Vec<i32>,
}
Will expand into:
pub struct MyStruct {
required_field: u32,
into_required_field: String,
standard_optional_field: bool,
custom_default_field: String,
list_field: Vec<i32>,
}
impl MyStruct {
pub fn builder() -> my_struct::Builder<my_struct::RequiredFieldStage> {
// ...
}
}
pub mod my_struct {
pub struct Builder<T> {
// ...
}
impl Default for Builder<RequiredFieldStage> {
fn default() -> Self {
// ...
}
}
impl Builder<RequiredFieldStage> {
pub fn required_field(self, required_field: u32) -> Builder<IntoRequiredFieldStage> {
// ...
}
}
impl Builder<IntoRequiredFieldStage> {
pub fn into_required_field(self, into_required_field: impl Into<String>) -> Builder<FinalStage> {
// ...
}
}
impl Builder<FinalStage> {
pub fn standard_optional_field(self, standard_optional_field: bool) -> Self {
// ...
}
pub fn custom_default_field(self, custom_default_field: String) -> Self {
// ...
}
pub fn push_list_field(self, list_field: i32) -> Self {
// ...
}
pub fn list_field(self, list_field: impl IntoIterator<Item = i32>) -> Self {
// ...
}
pub fn extend_list_field(self, list_field: impl IntoIterator<Item = i32>) -> Self {
// ...
}
pub fn build(self) -> super::MyStruct {
// ...
}
}
pub struct RequiredFieldStage {
// ...
}
pub struct IntoRequiredFieldStage {
// ...
}
pub struct FinalStage {
// ...
}
}