1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
// #![allow(rustdoc::broken_intra_doc_links)]
/// The `Builder` derive macro provides a convenient and ergonomic way to create builder patterns for struct types in Rust.
/// It allows you to generate builder methods for constructing instances of a struct with various features and constraints, all checked at compile time.
/// Below are the highlighted features and explanations for each, along with examples:
/// # Features
/// ## 1. Compile-Time Validity Checking
///
/// The `Builder` derive macro ensures that the constructed struct is valid at compile time.
/// This means that it checks that all required fields are provided and that group constraints are satisfied.
/// If any constraints are violated, the code will not compile.
///
/// ### Examples:
/// Basic example
/// ```rust
/// use const_typed_builder::Builder;
/// #[derive(Builder)]
/// pub struct Foo {
/// bar: String,
/// baz: String,
/// }
///
/// let foo = Foo::builder()
/// .bar("Hello".to_string()) // Mandatory field
/// .baz("Hello".to_string()) // Mandatory field
/// .build();
/// ```
///
/// This will not compile without providing 'baz'
/// ```compile_fail
/// # use const_typed_builder::Builder;
/// #[derive(Builder)]
/// pub struct Foo {
/// bar: String,
/// baz: String,
/// }
///
/// let foo = Foo::builder()
/// .bar("Hello".to_string()) // Mandatory field
/// .build();
/// ```
///
/// ## 2. Mandatory, Skipped and Optional Fields
///
/// By default, all fields in the generated builder are considered mandatory, meaning they must be provided during construction.
/// However, fields with the `Option` type are considered optional and can be left unset, and thus defaulted to `None`.
///
/// Fields can be either Mandatory, Skipped, Optional or Grouped (see next subsection), these are mutually exclusive.
/// ### Example:
/// Valid construction with optional field left unset
/// ```rust
/// # use const_typed_builder::Builder;
/// #[derive(Builder)]
/// pub struct Foo {
/// bar: String, // Mandatory
/// baz: Option<String>, // Optional
/// }
///
/// let foo = Foo::builder()
/// .bar("Hello".to_string())
/// .build();
/// ```
///
/// You can also specify that an `Option` field is in fact mandatory by using the attribute `mandatory`
///
/// ### Example:
/// Invalid construction with optional field left unset:
/// ```compile_fail
/// # use const_typed_builder::Builder;
/// #[derive(Builder)]
/// pub struct Foo {
/// bar: String, // Mandatory
/// #[builder(mandatory)]
/// baz: Option<String>, // Mandatory (but of type `Option`)
/// }
///
/// let foo = Foo::builder()
/// .bar("Hello".to_string())
/// .build();
/// ```
///
/// Or you can assume everything is mandatory altogether with `assume_mandatory` and `optional`.
///
/// ```
/// # use const_typed_builder::Builder;
/// #[derive(Builder)]
/// #[builder(assume_mandatory)]
/// pub struct Foo {
/// bar: Option<String>,
/// baz: Option<String>,
/// #[builder(optional)]
/// quz: Option<String>,
/// }
/// let foo = Foo::builder().bar("Hello world!".to_string()).baz("Hello world!".to_string()).build();
/// ```
///
/// You can also skip fields. This can be used if you still want to deserialize deprecated fields for instance.
/// ```compile_fail
/// # use const_typed_builder::Builder;
/// #[derive(Builder)]
/// pub struct Foo {
/// bar: String, // Mandatory
/// #[builder(skip)]
/// baz: Option<String>, // Skipped. The builder will leave it as `None`.
/// }
///
/// let foo = Foo::builder()
/// .bar("Hello".to_string())
/// .baz("World".to_string()) // This function does not exist
/// .build();
/// ```
/// ## 3. Grouped Fields
///
/// Fields can be grouped together, and constraints can be applied to these groups.
/// Groups allow you to ensure that a certain combination of fields is provided together.
/// There are four types of groups: `single`, `at_least`, `at_most`, and `exact`.
///
/// **All** fields that are grouped need to be an `Option` type.
///
/// - `single`: Ensures that only one field in the group can be provided. (It's basically a shorthand for `exact(1)`)
/// - `at_least(n)`: Requires at least `n` fields in the group to be provided.
/// - `at_most(n)`: Allows at most `n` fields in the group to be provided.
/// - `exact(n)`: Requires exactly `n` fields in the group to be provided.
///
/// The range of n is 1..=k, where k is the amount of fields that are associated with this group.
/// Errors will be emitted if the group can never be valid, or can be replaced by `skip` or `mandatory`.
/// Warnings will be emitted if the group is always valid, or can be replaced by `optional`.
///
/// ### Examples:
///
/// Valid construction only one field in `my_group` is provided
/// ```rust
/// # use const_typed_builder::Builder;
/// #[derive(Builder)]
/// #[group(my_group = single)]
/// pub struct Foo {
/// #[builder(group = my_group)]
/// bar: Option<String>,
/// #[builder(group = my_group)]
/// baz: Option<String>,
/// }
///
/// let foo = Foo::builder()
/// .baz("World".to_string())
/// .build();
/// ```
/// Invalid construction because both fields in `my_group` are provided
/// ```compile_fail
/// # use const_typed_builder::Builder;
/// #[derive(Builder)]
/// #[group(my_group = single)]
/// pub struct Foo {
/// #[builder(group = my_group)]
/// bar: Option<String>,
/// #[builder(group = my_group)]
/// baz: Option<String>,
/// }
///
/// let foo = Foo::builder()
/// .bar("Hello".to_string())
/// .baz("World".to_string())
/// .build();
/// ```
/// Valid construction because at least 2 fields in `my_group` are provided:
/// ```rust
/// # use const_typed_builder::Builder;
/// #[derive(Builder)]
/// #[group(my_group = at_least(2))]
/// pub struct Foo {
/// #[builder(group = my_group)]
/// bar: Option<String>,
/// #[builder(group = my_group)]
/// baz: Option<String>,
/// #[builder(group = my_group)]
/// qux: Option<String>,
/// }
///
/// let foo = Foo::builder()
/// .bar("Hello".to_string())
/// .baz("World".to_string())
/// .build();
/// ```
/// You can also add multiple groups to each field
///
/// Valid construction because at least 2 fields in 'least' are provided, and 'fred' had to be provided to validate the group 'most':
/// ```rust
/// # use const_typed_builder::Builder;
/// #[derive(Builder)]
/// #[group(least = at_least(2))]
/// #[group(most = at_most(3))]
/// pub struct Foo {
/// #[builder(group = least, group = most)]
/// bar: Option<String>,
/// #[builder(group = least, group = most)]
/// baz: Option<String>,
/// #[builder(group = least, group = most)]
/// qux: Option<String>,
/// #[builder(group = least, group = most)]
/// quz: Option<String>,
/// #[builder(group = most)]
/// fred: Option<String>,
/// }
///
/// let foo = Foo::builder()
/// .bar("Hello".to_string())
/// .baz("World".to_string())
/// .fred("!".to_string())
/// .build();
/// ```
///
/// ## 4. Propagating Builder for Complex Structs
///
/// If a field in the struct is of a complex type that also derives the `Builder` trait, you can propagate the construction of that field to its builder using the `propagate` attribute.
///
/// *Disclaimer* I'm still working a lot on this feature and I may change how it works. (I would love for the user to return the builder at the end of the function instead of calling `.builder()` by hand)
///
/// ### Example:
/// Valid construction with complex struct 'Bar' created within 'Foo'
/// ```rust
/// # use const_typed_builder::Builder;
/// #[derive(Builder)]
/// pub struct Foo {
/// #[builder(propagate)]
/// bar: Bar,
/// }
///
/// #[derive(Builder)]
/// pub struct Bar {
/// baz: String,
/// }
///
/// let foo = Foo::builder()
/// .bar(|builder| builder.baz("Hello world!".to_string()).build())
/// .build();
/// ```
///
/// ## 6. Generic Structs
///
/// The `Builder` derive macro supports generic structs, allowing you to generate builders for generic types with constraints, such as default values for generic parameters.
///
/// *Disclaimer* I haven't finished testing this feature yet
///
/// ### Example:
/// Valid construction for a generic struct 'Foo' with a default generic parameter
/// ```rust
/// # use const_typed_builder::Builder;
/// #[derive(Builder)]
/// pub struct Foo<A>
/// where
/// A: Into<u64>,
/// {
/// bar: A,
/// }
///
/// let foo = Foo::<u8>::builder()
/// .bar(42)
/// .build();
/// ```
///
/// These are the key features and explanations of the `Builder` derive macro in Rust, along with examples illustrating each feature. This macro simplifies the process of creating builders for your structs while ensuring compile-time safety and correctness.
pub use Builder;
/// The `Builder` trait facilitates the creation of builder patterns for Rust struct types. It provides a common interface for generating builders that enable the construction of instances of a struct with various configurations and compile-time validity checking.