You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
`bon` is a Rust crate for generating compile-time-checked builders for functions and structs. It also provides idiomatic partial application with optional and named parameters for functions and methods.
<td><a href="https://bon-rs.com/reference/builder">🔍 API Reference</a></td>
40
+
<td>Attributes API index</td>
41
+
</tr>
42
+
</tbody>
43
+
</table>
44
+
</div>
36
45
37
-
Visit the [guide for a complete overview of the crate](https://bon-rs.com/guide/overview).
46
+
<!-- #region overview -->
38
47
39
-
## Quick examples
48
+
#Announcement
40
49
41
-
### Builder for a free function
50
+
Release `3.0.0-rc` (release-candidate) was published 🎉. The ultimate stable `3.0.0` release is scheduled for 13-th of November. You are encouraged to use the `3.0.0-rc` version in the meantime and post your feedback in [#156](https://github.com/elastio/bon/issues/156). The release blog post will be ready on the scheduled release date, until then see the [changelog](https://bon-rs.com/changelog) for details.
42
51
43
-
You can turn a function with positional parameters into a function with named parameters just by placing the `#[builder]` attribute on top of it.
52
+
# Overview
53
+
54
+
`bon` is a Rust crate for generating compile-time-checked builders for structs and functions. It also provides idiomatic partial application with optional and named parameters for functions and methods.
55
+
56
+
If you wonder "Why would I use builders?", see the [motivational blog post](https://bon-rs.com/blog/how-to-do-named-function-arguments-in-rust).
57
+
58
+
## Function Builder
59
+
60
+
You can turn a function with positional parameters into a function with named parameters with `#[builder]`.
44
61
45
62
```rust
46
63
usebon::builder;
@@ -60,9 +77,44 @@ let greeting = greet()
60
77
assert_eq!(greeting, "Hello Bon! Your level is 24");
61
78
```
62
79
63
-
### Builder for an associated method
80
+
Any syntax for functions is supported including `async`, fallible, generic functions, `impl Trait`, etc.
81
+
82
+
Many things are customizable with additional attributes described in the [API reference](https://bon-rs.com/reference/builder), but let's see what else `bon` has to offer.
83
+
84
+
## Struct Builder
64
85
65
-
For associated methods you also need to add the `#[bon]` macro on top of the impl block.
86
+
Use `#[derive(Builder)]` to generate a builder for a struct.
87
+
88
+
```rust
89
+
usebon::Builder;
90
+
91
+
#[derive(Builder)]
92
+
structUser {
93
+
name:String,
94
+
is_admin:bool,
95
+
level:Option<u32>,
96
+
}
97
+
98
+
letuser=User::builder()
99
+
.name("Bon".to_owned())
100
+
// `level` is optional, we could omit it here
101
+
.level(24)
102
+
// call setters in any order
103
+
.is_admin(true)
104
+
.build();
105
+
106
+
assert_eq!(user.name, "Bon");
107
+
assert_eq!(user.level, Some(24));
108
+
assert!(user.is_admin);
109
+
```
110
+
111
+
## Method Builder
112
+
113
+
Associated methods require `#[bon]` on top of the impl block additionally.
114
+
115
+
### Method `new`
116
+
117
+
The method named `new` generates `builder()/build()` methods.
66
118
67
119
```rust
68
120
usebon::bon;
@@ -72,74 +124,122 @@ struct User {
72
124
name:String,
73
125
}
74
126
75
-
#[bon]// <- this attribute is required on impl blocks that contain `#[builder]`
127
+
#[bon]
76
128
implUser {
77
129
#[builder]
78
130
fnnew(id:u32, name:String) ->Self {
79
131
Self { id, name }
80
132
}
133
+
}
134
+
135
+
letuser=User::builder()
136
+
.id(1)
137
+
.name("Bon".to_owned())
138
+
.build();
139
+
140
+
assert_eq!(user.id, 1);
141
+
assert_eq!(user.name, "Bon");
142
+
```
143
+
144
+
`#[derive(Builder)]` on a struct generates builder API that is fully compatible with placing `#[builder]` on the `new()` method with a signature similar to the struct's fields (more details on the [Compatibility](https://bon-rs.com/guide/basics/compatibility#switching-between-derive-builder-and-builder-on-the-new-method) page).
145
+
146
+
### Other Methods
81
147
148
+
All other methods generate `{method_name}()/call()` methods.
format!("[{level}] {name} says hello to {target}")
164
+
format!("[{prefix}] {name} says hello to {target}")
88
165
}
89
166
}
90
167
91
-
// The method named `new` generates `builder()/build()` methods
92
-
letuser=User::builder()
93
-
.id(1)
94
-
.name("Bon".to_owned())
95
-
.build();
168
+
letgreeter=Greeter { name:"Bon".to_owned() };
96
169
97
-
// All other methods generate `method_name()/call()` methods
98
-
letgreeting=user
170
+
letgreeting=greeter
99
171
.greet()
100
172
.target("the world")
101
-
// `level` is optional, we can omit it here
173
+
// `prefix` is optional, omitting it is fine
102
174
.call();
103
175
104
-
assert_eq!(user.id, 1);
105
-
assert_eq!(user.name, "Bon");
106
176
assert_eq!(greeting, "[INFO] Bon says hello to the world");
107
177
```
108
178
109
-
### Builder for a struct
179
+
Methods with or without `self` are both supported.
110
180
111
-
The `#[derive(Builder)]` macro generates a builder for a struct.
181
+
## No Panics Possible
112
182
113
-
```rust
114
-
usebon::Builder;
183
+
Builders generated by `bon`'s macros use the typestate pattern to ensure all required parameters are filled, and the same setters aren't called repeatedly to prevent unintentional overwrites. If something is wrong, a compile error will be created.
115
184
116
-
#[derive(Builder)]
117
-
structUser {
118
-
name:String,
119
-
is_admin:bool,
120
-
level:Option<u32>,
121
-
}
185
+
| ⭐ Don't forget to give our repo a [star on Github ⭐](https://github.com/elastio/bon)! |
What you've seen above is the first page of the 📖 Guide Book. If you want to learn more, jump to the [Basics](https://bon-rs.com/guide/basics) section. And remember: knowledge is power 🐱!
191
+
192
+
Feel free to jump to code and use the `#[builder]` and `#[derive(Builder)]` once you've seen enough docs to get started.
193
+
194
+
The [🔍 API Reference](https://bon-rs.com/reference/builder) will help you navigate the attributes once you feel comfortable with the basics of `bon`. Both `#[derive(Builder)]` on structs and `#[builder]` on functions/methods have almost identical attributes API, so the documentation for them is common.
195
+
196
+
## Installation
197
+
198
+
Add `bon` to your `Cargo.toml`.
199
+
200
+
```toml
201
+
[dependencies]
202
+
bon = "2.3"
134
203
```
135
204
136
-
See [the guide](https://bon-rs.com/guide/overview) for more.
205
+
You can opt out of `std` and `alloc` cargo features with `default-features = false` for `no_std` environments.
206
+
207
+
## Acknowledgments
208
+
209
+
This project was heavily inspired by such awesome crates as [`buildstructor`](https://docs.rs/buildstructor), [`typed-builder`](https://docs.rs/typed-builder) and [`derive_builder`](https://docs.rs/derive_builder). This crate was designed with many lessons learned from them.
210
+
211
+
See [alternatives](https://bon-rs.com/guide/alternatives) for comparison.
212
+
213
+
## Who's Using `bon`?
137
214
138
-
---
215
+
Some notable users:
139
216
140
-
If you like the idea of this crate and want to say "thank you" or "keep doing this" consider giving us a [star ⭐ on Github](https://github.com/elastio/bon). Any support and contribution are appreciated 🐱!
If you can't figure something out, consult the docs and maybe use the `🔍 Search` bar on our [docs website](https://bon-rs.com). You may also create an issue or a discussion on the [Github repository](https://github.com/elastio/bon) for help or write us a message on [Discord](https://bon-rs.com/discord).
0 commit comments