In this lesson, you will learn how to use Rust’s type system to ensure that a builder can only be "built" once all required configuration steps have been completed at compile time.
The "State-Tracking" Builder
A standard builder pattern often relies on runtime checks (like Option::unwrap()) to see if a field was set. With generics, we can encode the state of the builder into its type. By changing the generic parameter of the builder as methods are called, we make it impossible to call .build() until the internal state is ready.
Consider a DatabaseConnection builder that requires a host to be set before it can be used. We can define empty "state" structs to track this progress:
struct Uninitialized;
struct Configured;
struct Builder<State> {
host: Option<String>,
_state: std::marker::PhantomData<State>,
}
impl Builder<Uninitialized> {
pub fn new() -> Self {
Self { host: None, _state: std::marker::PhantomData }
}
pub fn host(self, host: String) -> Builder<Configured> {
Builder {
host: Some(host),
_state: std::marker::PhantomData,
}
}
}
impl Builder<Configured> {
pub fn build(self) -> String {
self.host.unwrap()
}
}
Why This Works
In the code above, the host() method consumes Builder<Uninitialized> and returns Builder<Configured>. If you try to call .build() immediately after Builder::new(), the Rust compiler will throw an error: no method named build found for struct Builder<Uninitialized>.
This pattern provides two massive benefits:
- Zero Runtime Overhead: The
PhantomDataand state structs vanish at compile time. There is noif self.host.is_none()check inside thebuild()method, because the type system guarantees the host is present. - Developer Experience: Users of your API get immediate feedback. They don't have to guess which methods are required; the IDE and compiler guide them through the valid "state machine" of your configuration.
Key Takeaway: By using generic state parameters, you can turn runtime configuration errors into compile-time impossibility, ensuring your builder is always in a valid state before completion.