Skip to content

Commit 785ee15

Browse files
chore: release v3.0.0-rc (#179)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Veetaha <[email protected]>
1 parent f8b20e9 commit 785ee15

File tree

9 files changed

+167
-316
lines changed

9 files changed

+167
-316
lines changed

Cargo.lock

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 154 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
11
<a href="https://bon-rs.com/guide/overview">
2-
<!--
3-
We use an absolute link to the image here because this README is hosted on crates.io,
4-
lib.rs and docs.rs where this image isn't available through the relative link.
5-
-->
62
<img
73
src="https://bon-rs.com/bon-home.png"
84
alt="bon home"
95
/>
106
</a>
117

12-
<p align="center">
8+
<div align="center">
139
<a href="https://github.com/elastio/bon"><img
1410
alt="github"
1511
src="https://img.shields.io/badge/github-elastio/bon-228b22?style=for-the-badge&labelColor=555555&logo=github"
@@ -25,22 +21,43 @@
2521
src="https://img.shields.io/badge/docs.rs-bon-3b74d1?style=for-the-badge&labelColor=555555&logo=docs.rs"
2622
height="25"
2723
/></a>
28-
<a href="https://docs.rs/bon/latest/bon/"><img
24+
<a href="https://docs.rs/bon/latest/bon/"><img
2925
alt="docs.rs"
3026
src="https://img.shields.io/badge/MSRV-1.59.0-b83fbf?style=for-the-badge&labelColor=555555&logo=docs.rs"
3127
height="25"
3228
/></a>
33-
</p>
29+
</div>
3430

35-
`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.
31+
<div align="center">
32+
<table>
33+
<tbody>
34+
<tr>
35+
<td><a href="https://bon-rs.com/guide/overview">📖 Guide Book</a></td>
36+
<td>Narrative introduction</td>
37+
</tr>
38+
<tr>
39+
<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>
3645

37-
Visit the [guide for a complete overview of the crate](https://bon-rs.com/guide/overview).
46+
<!-- #region overview -->
3847

39-
## Quick examples
48+
# Announcement
4049

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.
4251

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]`.
4461

4562
```rust
4663
use bon::builder;
@@ -60,9 +77,44 @@ let greeting = greet()
6077
assert_eq!(greeting, "Hello Bon! Your level is 24");
6178
```
6279

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
6485

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+
use bon::Builder;
90+
91+
#[derive(Builder)]
92+
struct User {
93+
name: String,
94+
is_admin: bool,
95+
level: Option<u32>,
96+
}
97+
98+
let user = 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.
66118

67119
```rust
68120
use bon::bon;
@@ -72,74 +124,122 @@ struct User {
72124
name: String,
73125
}
74126

75-
#[bon] // <- this attribute is required on impl blocks that contain `#[builder]`
127+
#[bon]
76128
impl User {
77129
#[builder]
78130
fn new(id: u32, name: String) -> Self {
79131
Self { id, name }
80132
}
133+
}
134+
135+
let user = 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
81147

148+
All other methods generate `{method_name}()/call()` methods.
149+
150+
```rust
151+
use bon::bon;
152+
153+
struct Greeter {
154+
name: String,
155+
}
156+
157+
#[bon]
158+
impl Greeter {
82159
#[builder]
83-
fn greet(&self, target: &str, level: Option<&str>) -> String {
84-
let level = level.unwrap_or("INFO");
160+
fn greet(&self, target: &str, prefix: Option<&str>) -> String {
161+
let prefix = prefix.unwrap_or("INFO");
85162
let name = &self.name;
86163

87-
format!("[{level}] {name} says hello to {target}")
164+
format!("[{prefix}] {name} says hello to {target}")
88165
}
89166
}
90167

91-
// The method named `new` generates `builder()/build()` methods
92-
let user = User::builder()
93-
.id(1)
94-
.name("Bon".to_owned())
95-
.build();
168+
let greeter = Greeter { name: "Bon".to_owned() };
96169

97-
// All other methods generate `method_name()/call()` methods
98-
let greeting = user
170+
let greeting = greeter
99171
.greet()
100172
.target("the world")
101-
// `level` is optional, we can omit it here
173+
// `prefix` is optional, omitting it is fine
102174
.call();
103175

104-
assert_eq!(user.id, 1);
105-
assert_eq!(user.name, "Bon");
106176
assert_eq!(greeting, "[INFO] Bon says hello to the world");
107177
```
108178

109-
### Builder for a struct
179+
Methods with or without `self` are both supported.
110180

111-
The `#[derive(Builder)]` macro generates a builder for a struct.
181+
## No Panics Possible
112182

113-
```rust
114-
use bon::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.
115184

116-
#[derive(Builder)]
117-
struct User {
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)! |
186+
| --------------------------------------------------------------------------------------- |
122187

123-
let user = User::builder()
124-
.name("Bon".to_owned())
125-
// `level` is optional, we could omit it here
126-
.level(24)
127-
// call setters in any order
128-
.is_admin(true)
129-
.build();
188+
## What's Next?
130189

131-
assert_eq!(user.name, "Bon");
132-
assert_eq!(user.level, Some(24));
133-
assert!(user.is_admin);
190+
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"
134203
```
135204

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`?
137214

138-
---
215+
Some notable users:
139216

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 🐱!
217+
- [`crates.io` backend](https://github.com/rust-lang/crates.io)
218+
- [`ractor`](https://github.com/slawlor/ractor)
219+
- [`comrak`](https://github.com/kivikakk/comrak)
220+
- [`soldeer`](https://github.com/mario-eth/soldeer) (package manager endorsed by [`foundry`](https://github.com/foundry-rs/foundry))
221+
- [`tachyonfx`](https://github.com/junkdog/tachyonfx)
141222

142-
#### License
223+
## Getting Help
224+
225+
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).
226+
227+
## Socials
228+
229+
<table>
230+
<tbody>
231+
<tr>
232+
<td><a href="https://bon-rs.com/discord">Discord</a></td>
233+
<td>Here you can leave feedback, ask questions, report bugs, or just write "thank you".</td>
234+
</tr>
235+
<tr>
236+
<td><a href="https://x.com/veetaha" class="nobr">X (Twitter)</a></td>
237+
<td>Profile of the maintainer. There are only posts about <code>bon</code> and Rust in general here.</td>
238+
</tr>
239+
</tbody>
240+
</table>
241+
242+
## License
143243

144244
<sup>
145245
Licensed under either of <a href="https://github.com/elastio/bon/blob/master/LICENSE-APACHE">Apache License, Version
@@ -153,3 +253,5 @@ Unless you explicitly state otherwise, any contribution intentionally submitted
153253
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
154254
dual licensed as above, without any additional terms or conditions.
155255
</sub>
256+
257+
<!-- #endregion overview -->

0 commit comments

Comments
 (0)