You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
#[derive(Builder,Debug)]// -- Use anyhow::Error as the return type on validation error// -- Invoke MyStructBuilder::validate for validation#[builder(build_fn(error = "anyhow::Error", validate = "Self::validate"))]#[non_exhaustive]// Force construction via builder or ::new (outside the crate)pubstructMyStruct{pubage:u16,pubhappy:bool,pubweight:f32,// -- Allow anything that can convert into ...#[builder(setter(into))]pubfriends:Vec<String>,// -- Allow caller to skip setting this field#[builder(default)]// -- Avoid double wrapping Option#[builder(setter(into, strip_option))]pubid:Option<i32>,// -- Allow anything that can convert into String (eg. &str)#[builder(setter(into))]pubname:String,// -- you can always do: .host_name("any_string".try_into()?)// -- this also allows .try_host_name("any_string")?#[builder(try_setter, setter(into))]pubhost_name:HostName,// -- Don't generate setter for private field#[builder(setter(skip))]#[builder(default = "17")]something_hidden:i64,}
Usage
let v1 = MyStructBuilder::default()// <-- NOTICE: start with default on builder.age(123).friends(vec!["foo","bar"].into_iter().map(String::from).collect_vec()).happy(true).name("foo").weight(3.14).build().context("failed to build MyStruct")?;// NOTE: missing (non-optional) setter throws error: 'X' must be initialized
implMyStructBuilder{// Notice the validate fn is on the Builder structfnvalidate(&self) -> Result<(), anyhow::Error>{// TODO: more validation hereifletSome(v) = self.age{ensure!(v < 90,"too old: {v}");}Ok(())}}
Use non_exhaustive attribute to force users (outside the crate) to build via the ::newfn
Only forces validation Has no impact inside the crate, only affects other crates
#[derive(...)]#[non_exhaustive]// Force construction via ::new (outside the crate)pubstructMyStruct{pubfoo:Foo,pubbar:Bar,// ... other fields ...}implMyStruct{// ::new function is the "constructor" patternpubfnnew(foo:Foo,bar:Bar// ... all other fields ... <-- NOTICE you must pass ALL fields) -> Result<Self, anyhow::Error>{let out = Self{// ... assign ALL fields here ...};Self::validate(&out).context("Invalid MyStruct")?;Ok(out)}pubfnvalidate(data:&Self) -> Result<(), anyhow::Error>{// ... run validation here}
...
}