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
There are two problems with `#[derive(Builder)]` syntax in this case:
89
89
90
-
1. This refactoring becomes a breaking change to `Line`'s builder API 😢.
91
-
2. The private utility `Point` type leaks through the builder API via `point1`, and `point2` setters 😭.
90
+
1. This refactoring becomes a breaking change to `Line`'s builder API.
91
+
2. The private utility `Point` type leaks through the builder API via `point1`, and `point2` setters.
92
92
93
93
The fundamental problem is that the builder's API is _coupled_ ⛓️ with your struct's internal representation. It's literally `derive`d from the fields of your struct.
94
94
95
95
### Suffering
96
96
97
97
If you were using `typed-builder` or `derive_builder`, you'd be stuck for a while trying to find the magical 🪄 combination of attributes that would let you do this change without breaking compatibility or leakage of the private `Point` type.
98
98
99
-
With no solution in sight 😮💨, you'd then fall back to writing the same builder manually. You'd probably expand the builder derive macro and edit the generated code directly, which, ugh... hurts 🤕.
99
+
With no solution in sight, you'd then fall back to writing the same builder manually. You'd probably expand the builder derive macro and edit the generated code directly, which, ugh... hurts.
100
100
101
-
However, that would be especially painful with `typed-builder`, which generates a complex typestate that is not human-readable and maintainable enough by hand. It also references some internal `#[doc(hidden)]` symbols from the `typed-builder` crate. Achoo... 🤧.
101
+
However, that would be especially painful with `typed-builder`, which generates a complex typestate that is not human-readable and maintainable enough by hand. It also references some internal `#[doc(hidden)]` symbols from the `typed-builder` crate.
102
102
103
103
::: tip
104
104
105
-
In contrast, `bon`'s type state **is** human-readable, maintainable, and [documented](./typestate-api) 👍
105
+
In contrast, `bon`'s type state **is** human-readable, maintainable, and [documented](./typestate-api)
106
106
107
107
:::
108
108
109
109
### Behold the Function-Based Builder
110
110
111
-
This change is as simple as pie 🥧 with `bon` or `buildstructor`. The code speaks for itself:
111
+
This change is as simple as pie with `bon` or `buildstructor`. You need no more derives on a struct. Its internal representation can be decoupled from the builder by deriving the builder from a method:
112
112
113
113
```rust
114
114
usebon::bon;
115
115
116
-
// No more derives on a struct. Its internal representation is decoupled from the builder.
117
116
pubstructLine {
118
117
point1:Point,
119
118
point2:Point,
@@ -139,19 +138,15 @@ impl Line {
139
138
Line::builder().x1(1).y1(2).x2(3).y2(4).build();
140
139
```
141
140
142
-
Ah... Isn't this just so simple and beautiful? 😌 The fun part is that the constructor method `new` that we originally abandoned comes back to heroically save us ⛑️ at no cost, other than a star ⭐ on `bon`'s [Github repo](https://github.com/elastio/bon) maybe 🐈?
143
-
144
-
And you know what, our old friend `new` doesn't feel offended for being abandoned. It doesn't even feel emotions, actually 🗿. But it's happy to help you 🫂.
145
-
146
-
Moreover, it offers you a completely new dimension of flexibility:
141
+
Moreover, this approach offers you a completely new dimension of flexibility:
147
142
148
143
- Need some validation? Just change the `new()` method to return a `Result`. The generated `build()` method will then become fallible.
149
144
- Need to do an `async` operation in the constructor? Just make your constructor `async` and your `build()` will return a `Future`.
150
145
- Need some adrenaline 💉? Just add `unsafe`, and... you get the idea 😉.
151
146
152
147
---
153
148
154
-
The chances of hitting a wall with function builders are close to zero, and even if you ever do, you still have access to the [Typestate API](./typestate-api) in `bon` for even more flexibility 💪.
149
+
The chances of hitting a wall with function builders are close to zero, and even if you ever do, you still have access to the [Typestate API](./typestate-api) in `bon` for even more flexibility.
0 commit comments