Weekly Rust Trivia: How to Implement the Builder Pattern
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 our 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 fictitious 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 in a fluent style. By default, all fields are required, and build() returns an error if one of them is missing. Because the generated builder is Clone, all field types must implement Clone, which is why Transmission derives it. 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(())
}
This 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.
Looking for more Rust? Learn how to use pattern matching or how to share state between threads .