An opinionated macro implementation for Rust struct builder pattern with compile-time validation
APACHE-2.0 License
A derive macros to support a builder pattern for Rust:
Option<>
fields and explicitly defined default
attribute in structs are required, so you::new
and an auxiliary init struct definitionAdd this to your Cargo.toml
:
[dependencies]
rsb_derive = "0.4"
The macros generates the following functions and instances for your structures:
with/without/opt_<field_name>
: immutable setters for fields (opt
is an additional setter for Option<>
input argument)<field_name>/reset/mopt_<field_name>
: mutable setters for fields (mopt
is an additional setter for Option<>
input argument)new
: factory method with required fields as argumentsFrom<>
instance from an an auxiliary init struct definition with only required fields.<YourStructureName>Init
. So, you can use from(...)
or into()
// Import it
use rsb_derive::Builder;
// And use it on your structs
#[derive(Clone,Builder)]
struct MyStructure {
pub req_field1: String,
pub req_field2: i32,
pub opt_field1: Option<String>,
pub opt_field2: Option<i32>
}
// Creating instances
// Option #1:
let s1 : MyStructure = MyStructure::new(
"hey".into(),
0);
// Option #2 (named arguments emulation):
let s2 : MyStructure = MyStructureInit {
req_field1 : "hey".into(),
req_field2 : 0
}.into();
// Working with instances
let updated =
s1.clone()
.with_opt_field1("hey".into()) // for Option<> fields you specify a bare argument
.without_opt_field2() // you can reset Option<> if you need it
.opt_opt_field1(Some(("hey".into())) // you can use opt_<field> to provide Option<> inputs
.with_req_field2(10); // you can update required params as well
// All together example
let s1 : MyStructure =
MyStructure::from(
MyStructureInit {
req_field1 : "hey".into(),
req_field2 : 0
}
)
.with_opt_field1("hey".into())
.with_opt_field2(10);
// Mutable example (in case you really need it)
let mut s1 : MyStructure =
MyStructure::from(
MyStructureInit {
req_field1 : "hey".into(),
req_field2 : 0
}
);
s1
.opt_field1("hey".into()) // no prefix with for mutable setter
.opt_field2(10)
.field2(15)
.reset_opt_field2(); // mutable reset function for optional fields
While you're free to use the Rust Default
on your own structs or on auxiliary init structs
this lib intentionally ignores this approach and gives you an auxiliary default
attribute
to manage this like:
#[derive(Debug, Clone, PartialEq, Builder)]
struct StructWithDefault {
pub req_field1: String,
#[default="10"]
pub req_field2: i32, // default here make this field behave like optional
pub opt_field1: Option<String>,
#[default="Some(11)"]
pub opt_field2: Option<i32> // default works also on optional fields
}
let my_struct : StructWithDefault = StructWithDefault::from(
StructWithDefaultInit {
req_field1 : "test".into()
}
);
Apache Software License (ASL)
Abdulla Abdurakhmanov