JElgar / auto_builder

Derive safe builders for rust structs

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Auto Builder

A handy utility to generate "safe" builders for your rust types.

The issue with the builder pattern usually is some fields are required. If those fields are not provided before calling build then a run time error will be thrown. The builders generated by this package do not have this issue as the build method will not be available unless all required fields are set. Trying to call build before all required fields are set will result in a compile time error šŸ„³.

Usage

Don't actually use this package... There's a better ones:

use auto_builder_derive::Builder;

#[derive(Builder)]
struct A {
    x: i32,
    y: i32,
    z: String,
}

// Compiler error - missing `y`
let a = A::builder()
	.set_x(1)
	.set_z("abc")
	.build();

// Success!
let a = A::builder()
	.set_x(1)
	.set_y(2)
	.set_z("abc")
	.build();

What gets generated?

When a type derives Builder the following is generated:

  1. A struct with the name + Builder is generated. E.g. for struct Foo, FooBuilder is created.
  2. A new method is implemented for that builder and a builder method is implemented for the original type in-order. These can both be used to created a new builder.
  3. A setter method is implement on the builder for each field in the struct. The names are setter_ the field name. E.g. for field bar the method would be set_bar.
  4. A build method is implement for the builder when all required types are set.

Optional

Optional fields work as expected. If a field's type is Option<T> then the setter is not required to be called before build. If the setter is not called the field will be assigned to None.

Default

A required field can have a default value set. The field type must implement the Default trait and then the attribute [auto_builder(default)] can be set on the field. If the setter is not called the value from the default method will be assigned to the field.

use auto_builder_derive::Builder;

struct A {
    x: i32,
    y: String,
}

impl Default for A {
    fn default() -> Self {
        A { x: 10, y: String::from("Hello world") }
    }
}

#[derive(Builder)]
struct B {
    #[auto_builder(default)]
    a: A,
    b: String,
}

let b = B::builder()
	.set_b("Hello world").build();

How does this work?

In order to only make the build method available when all required fields are set we track which fields are set using generics. For more details see https://www.youtube.com/watch?v=k8kd22jNcps

About

Derive safe builders for rust structs


Languages

Language:Rust 100.0%