infallible-builder
Macro crate for generating infallible Builder interfaces.
Example Usage
[]
= "0.0"
use Builder;
let person = builder
.name
.age
.build;
assert_eq!;
assert_eq!;
assert_eq!;
The base type must implement Default. To implement Default for structs with
non-Default fields, consider a crate like [smart-default]
(https://docs.rs/smart-default/latest/smart_default/):
use SmartDefault;
// Non-Default type
Design Philosophy
Compared to other crates (e.g. [derive_builder]
(https://docs.rs/derive_builder/latest/derive_builder/index.html),
[typed-builder]
(https://docs.rs/typed-builder/latest/typed_builder/index.html)),
infallible-builder is more opinionated. It
generates builder types only with the following restrictions:
- Builders do not require fields, i.e.
MyType::builder().build()is always allowed - Builder methods are thin setters, at most calling
.into() - Builders do not contain additional logic or functionality, such as validation or serialization
This has some direct benefits:
- The
build()method is always infallible, improving ergonomics - The builder interface is self apparent from the base struct
infallible-builder makes other opinionated choices with the goal of builders
for different base structs having consistent interfaces:
setter(into, strip_option)is configured by default- The "owned" pattern is used rather than the "mutable" pattern, since "mutable"
disallows structs with non-
Clonefields
It is this crate author's opinion that builder customizability is ultimately detrimental, mostly enabling use cases where builders are not an ideal fit.
Implementation Notes
As of 0.0, this is implemented as attribute proc macro that adds
derive_builder::Builder to the annotated struct. As a result, some
#[builder()] annotations supported by derive_builder are respected, however
this behavior may change in the future.