• Stars
    star
    847
  • Rank 53,812 (Top 2 %)
  • Language
    Rust
  • License
    Apache License 2.0
  • Created about 7 years ago
  • Updated 8 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Compile-time type-checked builder derive

Build Status Latest Version Rust Documentation

Rust Typed Builder

Creates a compile-time verified builder:

use typed_builder::TypedBuilder;

#[derive(TypedBuilder)]
struct Foo {
    // Mandatory Field:
    x: i32,

    // #[builder(default)] without parameter - use the type's default
    // #[builder(setter(strip_option))] - wrap the setter argument with `Some(...)`
    #[builder(default, setter(strip_option))]
    y: Option<i32>,

    // Or you can set the default
    #[builder(default=20)]
    z: i32,
}

Build in any order:

Foo::builder().x(1).y(2).z(3).build();
Foo::builder().z(1).x(2).y(3).build();

Omit optional fields(the one marked with #[default]):

Foo::builder().x(1).build()

But you can't omit non-optional arguments - or it won't compile:

Foo::builder().build(); // missing x
Foo::builder().x(1).y(2).y(3); // y is specified twice

Features

  • Custom derive for generating the builder pattern.
  • Ability to annotate fields with #[builder(setter(into))] to make their setters accept Into values.
  • Compile time verification that all fields are set before calling .build().
  • Compile time verification that no field is set more than once.
  • Ability to annotate fields with #[builder(default)] to make them optional and specify a default value when the user does not set them.
  • Generates simple documentation for the .builder() method.
  • Customizable method name and visibility of the .build() method.

Limitations

  • The build errors when you neglect to set a field or set a field describe the actual problem as a deprecation warning, not as the main error.
  • The generated builder type has ugly internal name and many generic parameters. It is not meant for passing around and doing fancy builder tricks - only for nicer object creation syntax(constructor with named arguments and optional arguments).
    • For the that reason, all builder methods are call-by-move and the builder is not cloneable. Saves the trouble of determining if the fields are cloneable...
    • If you want a builder you can pass around, check out derive-builder. It's API does not conflict with typed-builder's so you can be able to implement them both on the same type.

Conflicts

  • TypedBuilder accepts arbitrary Rust code for #[builder(default = ...)], but other custom derive proc-macro crates may try to parse them using the older restrictions that allow only literals. To solve this, use #[builder(default_code = "...")] instead.

Alternatives - and why typed-builder is better

  • derive-builder - does all the checks in runtime, returning a Result you need to unwrap.
  • safe-builder-derive - this one does compile-time checks - by generating a type for each possible state of the builder. Rust can remove the dead code, but your build time will still be exponential. typed-builder is encoding the builder's state in the generics arguments - so Rust will only generate the path you actually use.

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 Repositories

1

vim-vebugger

Yes, we do need another debugger plugin
Vim Script
425
star
2

vim-merginal

Fugitive extension to manage and merge Git branches
Vim Script
277
star
3

bevy-tnua

A floating character controller for Bevy
Rust
203
star
4

bevy-yoleck

Your Own Level Editor Creation Kit
Rust
172
star
5

rust-smart-default

Rust macro for automatically generating default
Rust
126
star
6

vim-dutyl

Coordinate D tools to work together for you
Vim Script
79
star
7

vim-smile

The power of :smile available to everyone
Vim Script
30
star
8

bevy-egui-kbgp

Better keyboard and gamepad story for egui in Bevy
Rust
20
star
9

nvim-moonicipal

Task runner with focus on rapidly changing personal tasks
Lua
15
star
10

nu_plugin_skim

Rust
14
star
11

woab

Widgets on Actors Bridge - a GUI microframework for combining GTK with Actix
Rust
14
star
12

vim-yankitute

regex powered yank+substitute
Vim Script
13
star
13

vim-makecfg

Database of `makeprg` and `errorformat` settings
Vim Script
13
star
14

vim-casetrate

Modify the case of identifiers
Vim Script
11
star
15

vimConfig

My vim configurations
Lua
11
star
16

rust-powerset-enum

Rust
11
star
17

nvim-impairative

Lua
11
star
18

vim-omnipytent

The all powerful Pythonic task runner
Python
10
star
19

nvim-buffls

Add LSP functionality to specific Neovim buffers
Lua
9
star
20

bevy-yoetz

Rust
8
star
21

rust-inherent-pub

Rust
7
star
22

vim-erroneous

The right way to handle errors
Vim Script
7
star
23

nvim-channelot

Operate Neovim jobs from Lua coroutines
Lua
6
star
24

breeze.vim

Html navigation like vim-easymotion, tag matching, tag highlighting and DOM navigation
Python
6
star
25

nvim-days-without

Lua
6
star
26

nvim-blunder

Run commands in the builtin terminal and parse their output to the quickfix list
Lua
4
star
27

vim-integrake

Abuse Rake to do project chores around Vim
Ruby
3
star
28

vim-tabnine-completefunc

A TabNine completefunc for Vim
Vim Script
2
star
29

vim-terminalogy

Show and tell with a shell
Vim Script
2
star
30

sidekick-jam-entry-danger-doofus

Rust
1
star
31

kosem

Test wizard for semi-automatic testing
Rust
1
star
32

rust-poc-macro-emit-data

Rust
1
star
33

bevy-game-jam-1-entry

Rust
1
star