Rust patterns

rust patterns to remember

Disclaimer: This is just a list of patterns that I found useful. It is not exhaustive and it is not a best practice list.

Builder pattern but with a single struct

https://rust-unofficial.github.io/patterns/patterns/creational/builder.html

The builder pattern use a builder struct to create a new struct. In this case, we can use the struct itself to create a new struct. This is useful when we have a struct with many optional fields and we want to create a new struct with only a few fields changed.

#[derive(Default)]
pub struct Foo {
    bar: Option<String>,
}

impl Foo {
    pub fn new() -> Foo {
        Foo {
            ..Default::default(),
        }
    }

    pub fn with_bar(mut self, bar: String) -> Foo {
        self.bar = Some(bar);
        self
    }
}

fn main() {
    let foo = Foo::new().with_bar("Y".to_string());
}

Question mark operator

https://doc.rust-lang.org/rust-by-example/std/result/question_mark.html

Simply put, the question mark operator is a shortcut for unwrapping a Result. It is used to propagate errors up the call stack.

Replace

fn do_something() -> Result<Response, MyCustomError> {
    let smth = do_something(); // returns Result<Response, RandomError>
    match smth {
        Ok(response) => {
            // do stuff
            Ok(response)
        }
        Err(e) => {
            // create custom error
            let error = MyCustomError::new(e);
            Err(e)
        }
    }
}

with


// impl from to use .into() method
impl From<MyCustomError> for RandomError {
    fn from(e: MyCustomError) -> Self {
        e
    }
}

fn do_something() -> Result<Response, MyCustomError> {
    let smth = do_something()?;
    // do stuff
    Ok(smth)
}