colin-kiegel
rust-derive-builder
Rust

derive builder implementation for rust structs

Last updated Jun 22, 2026
1.5k
Stars
100
Forks
13
Issues
0
Stars/day
Attention Score
71
Language breakdown
No language data available.
โ–ธ Files click to expand
README

Build [Rust version]() Documentation Latest version All downloads Downloads of latest version

Builder Pattern Derive

[Rust][rust] macro to automatically implement the builder pattern for arbitrary structs. A simple #[derive(Builder)] will generate a FooBuilder for your struct Foo with all setter-methods and a build method.

How it Works

use derive_builder::Builder;

#[derive(Default, Builder, Debug)] #[builder(setter(into))] struct Channel { token: i32, special_info: i32, // .. a whole bunch of other fields .. }

fn main() { // builder pattern, go, go, go!... let ch = ChannelBuilder::default() .special_info(42u8) .token(19124) .build() .unwrap(); println!("{:?}", ch); }

Note that we did not write any definition or implementation of ChannelBuilder. Instead the derive_builder crate acts on #[derive(Builder)] and generates the necessary code at compile time.

This is the generated boilerplate code you didn't need to write. :-)

,ignore
#[derive(Clone, Default)]
struct ChannelBuilder {
    token: Option<i32>,
    special_info: Option<i32>,
}

#[allow(dead_code)] impl ChannelBuilder { pub fn token<VALUE: Into<i32>>(&mut self, value: VALUE) -> &mut Self { let mut new = self; new.token = Some(value.into()); new } pub fn special_info<VALUE: Into<i32>>(&mut self, value: VALUE) -> &mut Self { let mut new = self; new.special_info = Some(value.into()); new } fn build( &self, ) -> Result<Channel, ChannelBuilderError> { Ok(Channel { id: match self.id { Some(ref value) => Clone::clone(value), None => { return Err( Into::into( ::derive_builder::UninitializedFieldError::from("id"), ), ) } }, token: match self.token { Some(ref value) => Clone::clone(value), None => { return Err( Into::into( ::derive_builder::UninitializedFieldError::from("token"), ), ) } }, specialinfo: match self.specialinfo { Some(ref value) => Clone::clone(value), None => { return Err( Into::into( ::derivebuilder::UninitializedFieldError::from("specialinfo"), ), ) } }, }) } }

Note: This is edited for readability. The generated code doesn't assume traits such as Into are in-scope, and uses full paths to access them.

Get Started

It's as simple as three steps:

  • Add derive_builder to your Cargo.toml either manually or
with cargo-edit:
  • cargo add derive_builder
  • Add use derive_builder::Builder;
  • Annotate your struct with #[derive(Builder)]

Usage and Features

  • Chaining: The setter calls can be chained, because they consume and return &mut self by default.
  • Builder patterns: You can opt into other builder patterns by preceding your struct (or field) with #[builder(pattern = "owned")] or #[builder(pattern = "immutable")].
  • Extensible: You can still define your own implementations for the builder struct and define additional methods. Just make sure to name them differently than the setter and build methods.
  • Documentation and attributes: Setter methods can be documented by simply documenting the corresponding field. Similarly #[cfg(...)] and #[allow(...)] attributes are also applied to the setter methods.
  • Hidden fields: You can skip setters via #[builder(setter(skip))] on each field individually.
  • Setter visibility: You can opt into private setter by preceding your struct with #[builder(private)].
  • Setter type conversions: With #[builder(setter(into))], setter methods will be generic over the input types โ€“ you can then supply every argument that implements the [Into][into] trait for the field type.
  • Setter strip option: With #[builder(setter(strip_option))], setter methods will take T as parameter type for field of type Option<T>.
  • Collection setters: Adding #[builder(setter(each(name = "method_name")))] to fields whose types implement Default and Extend will generate a setter which adds items to the builder collection for that field. It's possible for these setters to be generic over the Into<T> trait too, like so: #[builder(setter(each(name = "foo", into)))].
  • Builder field visibility: You can use #[builder(field(private))] or ..(public), to set field visibility of your builder.
  • Generic structs: Are also supported, but you must not use a type parameter named VALUE, if you also activate setter type conversions.
  • Default values: You can use #[builder(default)] to delegate to the Default implementation or any explicit value via = "..". This works both on the struct and field level.
  • Pre-build validation: You can use #[builder(build_fn(validate = "path::to::fn"))] to add your own validation before the target struct is generated.
  • Build method suppression: You can use #[builder(build_fn(skip))] to disable auto-implementation of the build method and provide your own.
  • Custom build method error types: You can use #[builder(build_fn(error = "path::to::Error"))] to have your builder return an error type of your choosing. By default, the macro will emit an error type alongside the builder.
  • Builder derivations: You can use #[builder(derive(Trait1, Trait2, ...))] to have the builder derive additonal traits. All builders derive Default and Clone, so you should not declare those in this attribute.
  • Pass-through attributes: Use #[builderstructattr(...)], #[builderimplattr(...)], #[builderfieldattr(...)], and #[buildersetterattr(...)] to declare attributes that will be added to the relevant part of the generated builder.
  • nostd support: Just add #[builder(nostd)] to your struct, use feature alloc, and add extern crate alloc to your crate.
  • No alloc nostd support: Do not use alloc feature and then either add #[builder(nostd, buildfn(error(validationerror = false)))] or #[builder(nostd, buildfn(error = "path::to::Error"))] to your struct.
  • Renaming and re-export support: Use #[builder(crate = "...")] to set the root for derivebuilder. This is useful if you want to rename derivebuilder in Cargo.toml or if your crate is re-exporting derivebuilder::Builder and needs the generated code to not directly reference the derivebuilder crate.
For more information and examples please take a look at our [documentation][doc].

Gotchas

  • Tuple structs and unit structs are not supported as they have no field names. We do not intend to support them.
  • When defining a generic struct, you cannot use VALUE as a generic parameter as this is what all setters are using.

[Documentation][doc]

Detailed explaination of all features and tips for troubleshooting. You'll also find a discussion of different builder patterns.

[doc]: https://colin-kiegel.github.io/rust-derive-builder [rust]: https://www.rust-lang.org/ [builder-pattern]: https://aturon.github.io/ownership/builders.html [into]: https://doc.rust-lang.org/nightly/std/convert/trait.Into.html

Changelog

Yes, we keep a changelog.

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

๐Ÿ”— More in this category

ยฉ 2026 GitRepoTrend ยท colin-kiegel/rust-derive-builder ยท Updated daily from GitHub