Hi folks,
I started using a simplified version of the Builder Pattern (I don't use the second FooBuilder
struct).
The idea is that I don't set all fields since some of those set functions might be resource-intensive and not all fields are always needed.
It works great, but now I need to add a field that needs to be Option<T>
and Option<T>
is already used to identify fields that haven't been set yet.
I could use Option<Option<T>>
but that doesn't feel right. Are there any best practices for that?
Thank you
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum Color {
Red,
Green,
Blue,
}
#[derive(Clone, Debug, Default, Eq, PartialEq)]
struct MyStruct {
name: Option<String>,
size: Option<u16>,
color: Option<Color>,
}
impl MyStruct {
fn new() -> Self {
Self::default()
}
fn set_name(mut self, name: &str) -> Self {
if self.name == None {
self.name = Some(name.to_owned());
}
self
}
fn set_size(mut self, size: u16) -> Self {
if self.size == None {
self.size = Some(size);
}
self
}
fn set_color(mut self, color: Color) -> Self {
if self.color == None {
self.color = Some(color);
}
self
}
}
fn main() {
let out = MyStruct::new().set_name("foo");
println!("{:?}", &out);
let out = out.set_size(123);
println!("{:?}", &out);
let out = out.set_size(333);
println!("{:?}", &out);
let out = out.set_color(Color::Green);
println!("{:?}", &out);
// MyStruct { name: Some("foo"), size: None, color: None }
// MyStruct { name: Some("foo"), size: Some(123), color: None }
// MyStruct { name: Some("foo"), size: Some(123), color: None }
// MyStruct { name: Some("foo"), size: Some(123), color: Some(Green) }
}