liveBook · Manning

Builder pattern

As explained in Write Powerful Rust Macros

The builder pattern constructs a complex value through an intermediate builder with configurable operations before finalization.

The builder pattern constructs a struct through a separate, fluent object. Instead of supplying many values at once, start with `builder()`, set fields through chained methods, then call `build()` to create the finished value. It is useful when structs require multiple parameters and hand-written builders would repeat boilerplate. section 6.0 section 6.9

A generated builder can store each incoming field as `Option<T>`. `builder()` initializes every slot to `None`; each setter saves `Some(input)` and returns the builder; `build()` reads the saved values to initialize the original struct. The initial implementation reports an unset required field during `build()`. section 6.4.2

Fluent construction

For a struct with `roots_of: String`, a builder call can read `Gleipnir::builder().roots_of("mountains".to_string()).build()`. The result contains the supplied value, and a black-box test can verify that public behavior without depending on macro internals. section 6.4.2 section 6.9

A derive macro can generate the helper builder without changing the original struct. It inspects named fields, emits storage, setters, `build()`, and the associated `builder()` function. This keeps the public construction API while automating repetitive implementation work. section 6.0 section 6.4.2

For stricter required-field handling, type state can make incomplete construction unbuildable. The builder carries a generic marker representing the next required field; each setter returns a builder with the next marker, and only the final marker specialization exposes `build()`. Omitting a field then becomes a compile-time missing-method error. section 8.5.2

Figure 8.6 Desired situation: illegal states are unrepresentable. We generate a struct with a different generic type parameter for every method, only allowing the last one to call build.
figure

This diagram captures the type-state progression: distinct generic builder states allow `build()` only after the final required setter. section 8.5.2

How Write Powerful Rust Macros covers it

How deep it goes
Works through generated field storage, setters, finalization, tests, and type-state enforcement of required fields.
Examples
Demonstrates a `Gleipnir` builder that sets String, u8, and bool fields, including a compile-fail missing-field case.
What it assumes
Assumes Rust struct and macro familiarity, then develops builder generation and testing incrementally.
What you can do after
Build it from scratch as a derive macro that generates fluent builders and can reject incomplete construction at compile time.
How it connects
Connects procedural derive macros, test-driven development, white-box testing, black-box testing, attributes, and type state.

Also explained in

Compare how 6 books explain builder pattern →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Write Powerful Rust Macros. The section links point to the parts of the book it draws on.