Another builder macro-based generator with its own idioms.
"Maçon" is French translation for "builder"
Usage
extern crate macon;
let _mytype: MyType = builder
.integer
.string
.build;
- adds a builder struct (
<TargetStruct>Builder) - build struct implements
Default - adds a
builder()function to target struct to initialize a new builder - each target struct field can be set with function of same name and parameter of same type
- use
build()function to create new target struct instance - any unset field will make
build()call not compile (default) - setter argument is generic over
Into Optionfields are not mandatory. And setters use wrapped type.
Settings
Settings are set using #[builder()] attribute.
struct
-
mode=<value>Change builder and associatedbuild()function behavior. Supported values:Typestate(default),PanicorResult. -
Default=!Disable automaticDefaultderive detection for struct. See "Defaultstruct". -
DefaultEnforceDefaultsupport for struct. See "Defaultstruct". -
Option=!(deprecated. Usefields(Option)instead.) -
Into=!(deprecated. Usefields(Into)instead.) -
fields(Option=!)Disable automaticOptiondetection for fields. See "Optionfields". -
fields(Default=!)Disable automaticDefaultdetection for fields. See "Defaultfields". -
fields(Into=!)DisableIntofor fields. See "Intoargument".
field
-
Option=!Disable automaticOptiondetection for given field. Generated setter will rely on declared field type. See "Optionfields". -
Option=WrappedTypeEnforceOptionsupport for given field. Generated setter will rely onWrappedType. See "Optionfields". -
Default=!Disable automaticDefaultdetection for given field. See "Defaultfields". -
DefaultEnforceDefaultsupport for given field. See "Defaultfields". -
Into=!DisableIntofor setter. See "Intoargument".
Features
For any feature, you can find blueprints in ./tests directory showing code generated by macro.
Typestate pattern (default)
Blueprints:
blueprint_typestate_named.rsblueprint_typestate_tuple.rsblueprint_typestate_option.rsblueprint_typestate_default_field.rsblueprint_typestate_default_struct.rs
By default, builder rely on typestate pattern. It means state is encoded in type (using generics). Applicable functions are implemented (callable) only when state (type) matches:
- Build function
build()when all properties has been set - Each property setter function as long as property haven't been set
Optionally, you can set it explictly:
extern crate macon;
// Builder signature
Panic on build()
Blueprints:
blueprint_panic_named.rsblueprint_panic_tuple.rsblueprint_panic_option.rsblueprint_panic_default_field.rsblueprint_panic_default_struct.rs
By default, builder rely on typestate pattern to avoid misconfiguration by adding compilation constraint. You can switch to a builder that just panic when misconfigured:
extern crate macon;
use PathBuf;
// Builder signature
let _mytype: MyType = builder
.integer
.build;
Result on build()
Blueprints:
blueprint_result_named.rsblueprint_result_tuple.rsblueprint_result_option.rsblueprint_result_default_field.rsblueprint_result_default_struct.rs
By default, builder rely on typestate pattern to avoid misconfiguration by adding compilation constraint. You can switch to a builder
that returns a Result:
extern crate macon;
use PathBuf;
// Builder signature
let myTypeResult: = builder
.integer
.build;
assert_eq!;
Tuple
Blueprints:
Tuples are struct with unamed fields. Then set<ordinal>() is used as setter:
extern crate macon;
;
// Builder signature
let _mytuple: MyTuple = builder
.set0
.set2
.build;
Only for Typestate mode, you can use set(), none(), keep() and default() calls to assign values in order:
extern crate macon;
;
// Builder signature
let _mytuple: MyTuple = builder
.set
.none
.set
.build;
Into argument
Blueprints:
Setter function argument is generic over Into to ease conversion (especially for &str):
extern crate macon;
;
// Builder signature
let _mytuple: MyTuple = builder
.set
.build;
You can disable Into support by using #[builder(Into=!)] at struct or field level:
extern crate macon;
// Disable for all fields
// Builder signature
# ;
let built = builder
.no_into
.with_into
.build;
assert_eq!;
assert_eq!;
This feature is required to use with dyn trait:
extern crate macon;
// Builder signature
builder
.function
.build;
Implement Into
Blueprints:
Builders implement Into for target type (and reverse From also). Except for Result mode which uses TryInto / TryFrom.
extern crate macon;
;
let _mytuple: MyStruct = builder
.value
.into;
Option fields
Blueprints:
As their name suggests, Option fields are facultative: you can build instance without setting them explicitly.
Setter argument are still generic over Into but for wrapped type. No need to wrap into an Option:
extern crate macon;
// Builder signature
let built = builder
.discretionary
.mandatory
.build;
assert_eq!;
You can set them explicitly to None with <field>_none() or none() for ordered setter:
extern crate macon;
// Builder signature
let built = builder
.discretionary_none
.mandatory
.build;
assert_eq!;
Note: In order to detect optional fields, field type name must match:
core::option::Option::core::option::Optionstd::option::Option::std::option::OptionOption
You can disable Option support by using #[builder(Option=!)] at struct or field level:
extern crate macon;
// Builder signature
let built = builder
.discretionary
.build;
assert_eq!;
If you use an alias, use #[builder(Option=<WrappedType>)] at field level to enable Option support:
extern crate macon;
type OptString = ;
// Builder signature
let built = builder
.discretionary
.build;
assert_eq!;
If you are already dealing with Option, use <field>_optional or optional for ordered setter:
extern crate macon;
// Builder signature
let discretionary = Some;
let built = builder
.discretionary_optional
.build;
assert_eq!;
Default struct
Blueprints:
blueprint_typestate_default_struct.rsblueprint_panic_default_struct.rsblueprint_result_default_struct.rs
If struct derives Default, all fields are then optional and values are kept from default instance:
Note: In order to detect Default derive, Builder derive attribute must be placed before other derive attributes.
extern crate macon;
let built = builder
.build;
assert_eq!;
In case Default derive detection is undesired, you can disable it with #[builder(Default=!)].
On the other hand, if have your own Default implementation, you can add #[builder(Default)] to enable support.
extern crate macon;
let built = builder
.build;
assert_eq!;
You can keep default value (from default built instance) explicitly with <field>_keep() or keep() for ordered setter:
// Builder signature
let built = builder
.integer_keep
.string
.optional_none
.build;
assert_eq!;
Default fields
Blueprints:
blueprint_typestate_default_field.rsblueprint_panic_default_field.rsblueprint_result_default_field.rs
If field implements Default, it is then optional and value is:
- kept from default instance if struct derives
Default, - or, initialized with default value.
extern crate macon;
// Builder signature
let built = builder
.build;
assert_eq!;
You can set them explicitly to default with <field>_default() or default() for ordered setter (e.g. override default instance value):
extern crate macon;
let built = builder
.integer_default
.string_default
.optional_default
.build;
assert_eq!;
In order to detect default fields, field type name must match (leading :: and module path are optionals):
boolcharf32f64i8i16i32i64i128isizestru8u16u32u64u128usizestd::string::Stringcore::option::Optionstd::option::Optionstd::vec::Vecalloc::vec::Vecstd::collections::HashMapstd::collections::hash_map::HashMapstd::collections::HashSetstd::collections::hash_set::HashSet
If you use an alias or unsupported type, use #[builder(Default)] at field level to enable Default support:
extern crate macon;
// Builder signature
let built = builder
.build;
assert_eq!;
You can disable Default support by using #[builder(Default=!)] at field level:
// Don't compile
extern crate macon;
builder
.integer_default
.build;