Thoughts on Rust Builder Pattern?
Tags: rust, discuss, watercooler
Published: 2021-06-13 09:48:35

**Update with Playground Builder Code**

Today I took a look at an interesting post related to JavaScript and the **Builder Pattern**

{% link coderslang/javascript-design-patterns-builder-290d %}

This got me wondering about Rust and the **Builder Pattern**  

This lead me to some interesting articles on the topic.

1. [GitHub](https://github.com/rust-unofficial/patterns/discussions/237)
2. [Users Rust Lang](https://users.rust-lang.org/t/builder-pattern-without-violating-dry/47525)
3. [Init Struct Pattern](https://xaeroxe.github.io/init-struct-pattern/)
4. [Rust Typed Builder](https://github.com/idanarye/rust-typed-builder)
5. [Rust Docs](https://doc.rust-lang.org/1.0.0/style/ownership/builders.html)

I presently have no opinion myself as I am rather new. But I was hoping some others with more experience might venture their opinions. It seems people are a bit split about the use of the **Builder Pattern** in rust.

You can access the [Playound](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=bdf9d2a0fde53ebcc1c142ea4d10f489)  
The [Gist](https://gist.github.com/bdf9d2a0fde53ebcc1c142ea4d10f489)

I used the following sample from [Rust Unoffical](https://rust-unofficial.github.io/patterns/patterns/creational/builder.html) as a starting point.

The code if you just want to see it:
```rust
#![allow(unused)]
#[derive(Debug, Clone)]
pub struct OTG<'a> {
    model: String,
    title: &'a str,
    color: String,
    max_temperature:u8,
    max_time_selection:u8,
}

impl<'a> Default for OTG<'a> {
    fn default() -> OTG<'a> {
        OTG {
            model: String::new(),
            title: "OTG",
            color: String::new(),
            max_temperature: 150,
            max_time_selection: 30,
        }
    }
    
}
impl<'a, 'b> OTG<'a> {
    fn new(model: String, color: String) -> Self {
        Self {
            model,
            color,
            ..OTG::default()
        }
    }
    pub fn builder() -> OTGBuilder<'b> {
        OTGBuilder::default()
    }
}

#[derive(Default, Clone)]
pub struct OTGBuilder<'b> {
    model: String,
    title: &'b str,
    color: String,
    max_temperature:u8,
    max_time_selection: u8
}

impl<'b> OTGBuilder<'b> {
    pub fn new() -> Self {
        Self {
            model: String::new(),
            color: String::new(),
            title: "OTG",
            max_temperature: 150,
            max_time_selection: 30,
        }
        
    }
    pub fn model(mut self, model: String) -> OTGBuilder<'b> {
        self.model = model;
        self
    }
    pub fn color(mut self, color: String) -> OTGBuilder<'b> {
        self.color = color;
        self
    }
    pub fn set_temp(mut self, temp: u8) -> OTGBuilder<'b> {
        self.max_temperature = temp;
        self
    }
    pub fn set_time(mut self, time:u8) -> OTGBuilder<'b> {
        self.max_time_selection = time;
        self
    }
    pub fn build(self) -> OTG<'b> {
        OTG {
            model: self.model.to_string(),
            color: self.color.to_string(),
            max_temperature: self.max_temperature,
            max_time_selection: self.max_time_selection,
            ..OTG::default()
        }
    }
    
    
}
fn main() {
    let otg = OTG::new("LG".to_string(), "Red".to_string());
    
    println!("Model: {}, Color: {} Temp: {}, Time: {}",
    otg.model, otg.color,
    otg.max_temperature, otg.max_time_selection
    );
    
    let otg_builder1: OTG = OTGBuilder::new()
                            .model(String::from("Builder1"))
                            .color("Red".to_string()).build();
    println!("Model: {}, Color: {} Temp: {}, Time: {}",
    otg_builder1.model, otg_builder1.color,
    otg_builder1.max_temperature, otg_builder1.max_time_selection
    );
    
    let otg_builder2: OTG = OTGBuilder::new()
                            .model(String::from("Builder1"))
                            .color("Red".to_string())
                            .set_temp(80).build();
    println!("Model: {}, Color: {} Temp: {}, Time: {}",
    otg_builder2.model, otg_builder2.color,
    otg_builder2.max_temperature, otg_builder2.max_time_selection
    );
    
    let otg_builder3: OTG = OTGBuilder::new()
                            .model(String::from("Builder1"))
                            .color("Red".to_string())
                            .set_temp(80)
                            .set_time(50).build();
    println!("Model: {}, Color: {} Temp: {}, Time: {}",
    otg_builder3.model, otg_builder3.color,
    otg_builder3.max_temperature, otg_builder3.max_time_selection
    );
    
    let otg_builder4: OTG = OTGBuilder::new()
                            .model(String::from("Builder1"))
                            .color("Red".to_string())
                            .set_time(50).build();
    println!("Model: {}, Color: {} Temp: {}, Time: {}",
    otg_builder4.model, otg_builder4.color,
    otg_builder4.max_temperature, otg_builder4.max_time_selection
    );
}
```

Looking forward to any comments and or responses.