Weekly Rust Trivia is a problem-oriented series of articles that assist developers while learning Rust. Every article solves simple, everyday development tasks using the Rust standard library or leveraging popular and proven crates.

Question: How to implement the builder pattern in Rust?

The derive_builder crate provides a macro which allows us to satisfy the builder pattern for your individual structs without writing custom code.

First let’s add the dependency using cargo add:

# Add derive_builder as dependency
cargo add derive_builder

Having the crate added to our project, we can move on and implement the builder pattern for the fictive struct Car:

use derive_builder::Builder;

#[derive(Builder, Debug)]
struct Car {
    color: String,
    transmission: Transmission,
    convertible: bool,
    mileage: u32,
}

#[derive(Clone, Debug)]
enum Transmission {
    Manual,
    SemiAuto,
    Automatic,
}

The code defines a struct called Car and an enum called Transmission. The Car struct is annotated with the Builder derive macro from the derive_builder crate. The Builder macro generates a builder pattern implementation for the Car struct - by automatically generating another struct called CarBuilder - allowing users to construct new Car instances with optional or defaulted fields in a fluent style. The Transmission enum defines three variants: Manual, SemiAuto, and Automatic.

We can use the automatically generated CarBuilder as shown here:

fn main() -> Result<(), Box<dyn std::error::Error>>{
    let car = CarBuilder::default()
        .color("red".to_string())
        .transmission(Transmission::Manual)
        .convertible(false)
        .mileage(10000)
        .build()?;

    println!("{:#?}", car);

    Ok(())
}

Which will print the debug representation of car:

# Car {
#    color: "red",
#    transmission: Manual,
#    convertible: false,
#    mileage: 10000,
#}

If you want to dive deeper into implementing the builder pattern in Rust, and see how to craft the builder pattern manually - without adding the derive_builder crate to your project, consider reading “Design Patterns in Rust: An Introduction to the Builder Pattern” from Engin Diri.