typed_builder/
lib.rs

1#![no_std]
2
3/// `TypedBuilder` is not a real type - deriving it will generate a `::builder()` method on your
4/// struct that will return a compile-time checked builder. Set the fields using setters with the
5/// same name as the struct's fields and call `.build()` when you are done to create your object.
6///
7/// Trying to set the same fields twice will generate a compile-time error. Trying to build without
8/// setting one of the fields will also generate a compile-time error - unless that field is marked
9/// as `#[builder(default)]`, in which case the `::default()` value of it's type will be picked. If
10/// you want to set a different default, use `#[builder(default=...)]`.
11///
12/// # Examples
13///
14/// ```
15/// use typed_builder::TypedBuilder;
16///
17/// #[derive(PartialEq, TypedBuilder)]
18/// struct Foo {
19///     // Mandatory Field:
20///     x: i32,
21///
22///     // #[builder(default)] without parameter - use the type's default
23///     // #[builder(setter(strip_option))] - wrap the setter argument with `Some(...)`
24///     #[builder(default, setter(strip_option))]
25///     y: Option<i32>,
26///
27///     // Or you can set the default
28///     #[builder(default=20)]
29///     z: i32,
30/// }
31///
32/// assert!(
33///     Foo::builder().x(1).y(2).z(3).build()
34///     == Foo { x: 1, y: Some(2), z: 3, });
35///
36/// // Change the order of construction:
37/// assert!(
38///     Foo::builder().z(1).x(2).y(3).build()
39///     == Foo { x: 2, y: Some(3), z: 1, });
40///
41/// // Optional fields are optional:
42/// assert!(
43///     Foo::builder().x(1).build()
44///     == Foo { x: 1, y: None, z: 20, });
45///
46/// // This will not compile - because we did not set x:
47/// // Foo::builder().build();
48///
49/// // This will not compile - because we set y twice:
50/// // Foo::builder().x(1).y(2).y(3);
51/// ```
52///
53/// # Customization with attributes
54///
55/// In addition to putting `#[derive(TypedBuilder)]` on a type, you can specify a `#[builder(...)]`
56/// attribute on the type, and on any fields in it.
57///
58/// On the **type**, the following values are permitted:
59///
60/// - `doc`: enable documentation of the builder type. By default, the builder type is given
61///   `#[doc(hidden)]`, so that the `builder()` method will show `FooBuilder` as its return type,
62///   but it won't be a link. If you turn this on, the builder type and its `build` method will get
63///   sane defaults. The field methods on the builder will be undocumented by default.
64///
65/// - `crate_module_path`: This is only needed when `typed_builder` is reexported from another
66///   crate - which usually happens when another macro uses it. In that case, it is the
67///   reponsibility of that macro to set the `crate_module_path` to the _unquoted_ module path from
68///   which the `typed_builder` crate can be accessed, so that the `TypedBuilder` macro will be
69///   able to access the typed declared in it.
70///
71///   Defaults to `#[builder(crate_module_path=::typed_builder)]`.
72///
73/// - The following subsections:
74///   - `builder_method(...)`: customize the builder method that creates the builder type
75///   - `builder_type(...)`: customize the builder type
76///   - `build_method(...)`: customize the final build method
77///
78///   All have the same fields:
79///   - `vis = "..."`: sets the visibility of the build method, default is `pub`
80///   - `name = ...`: sets the fn name of the build method, default is `build`
81///   - `doc = "..."` replaces the default documentation that will be generated for the
82///     `build()` method of the builder type. Setting this implies `doc`.
83///
84///
85/// - The `build_method(...)` subsection also has:
86///   - `into` or `into = ...`: change the output type of the builder. When a specific value/type
87///     is set via the assignment, this will be the output type of the builder. If no specific
88///     type is set, but `into` is specified, the return type will be generic and the user can
89///     decide which type shall be constructed. In both cases an [`Into`] conversion is required to
90///     be defined from the original type to the target type.
91///
92/// - The `builder_type(...)` subsection also has:
93///   - `attributes` - for adding attributes to the builder type. Note that the full attribute
94///     syntax is required **inside** this section -
95///     ```ignore
96///     #[builder(builder_type(attributes(
97///         #[derive(...)]
98///         #[some_other_attribute]
99///     )))]
100///     ```
101///
102///     Example:
103///     
104///     ```
105///     use typed_builder::TypedBuilder;
106///
107///     #[derive(TypedBuilder)]
108///     #[builder(builder_type(attributes(#[derive(Debug)])))]
109///     struct Foo {
110///         x: i32,
111///     }
112///     ```
113///
114/// - `field_defaults(...)` is structured like the `#[builder(...)]` attribute you can put on the
115///   fields and sets default options for fields of the type. If specific field need to revert some
116///   options to the default defaults they can prepend `!` to the option they need to revert, and
117///   it would ignore the field defaults for that option in that field.
118///
119///    ```
120///    use typed_builder::TypedBuilder;
121///
122///    #[derive(TypedBuilder)]
123///    #[builder(field_defaults(default, setter(strip_option)))]
124///    struct Foo {
125///        // Defaults to None, options-stripping is performed:
126///        x: Option<i32>,
127///
128///        // Defaults to 0, option-stripping is not performed:
129///        #[builder(setter(!strip_option))]
130///        y: i32,
131///
132///        // Defaults to Some(13), option-stripping is performed:
133///        #[builder(default = Some(13))]
134///        z: Option<i32>,
135///
136///        // Accepts params `(x: f32, y: f32)`
137///        #[builder(setter(!strip_option, transform = |x: f32, y: f32| Point { x, y }))]
138///        w: Point,
139///    }
140///
141///    #[derive(Default)]
142///    struct Point { x: f32, y: f32 }
143///    ```
144///
145/// - `mutators(...)` takes functions, that can mutate fields inside of the builder.
146///   See [mutators](#mutators) for details.
147///
148/// On each **field**, the following values are permitted:
149///
150/// - `default`: make the field optional, defaulting to `Default::default()`. This requires that
151///   the field type implement `Default`. Mutually exclusive with any other form of default.
152///
153/// - `default = ...`: make the field optional, defaulting to the expression `...`.
154///
155/// - `default_where(...)`: add trait bounds to the default. This means that the `default`
156///   expression (or type default) is allowed to rely on these bounds, but the field will not have
157///   a default if these trait bounds are not fulfilled.
158///
159///   Example:
160///
161///    ```
162///    use typed_builder::TypedBuilder;
163///
164///    #[derive(TypedBuilder)]
165///    struct Foo<T> {
166///        #[builder(default, default_where(T: Default))]
167///        bar: T,
168///    }
169///    ```
170///
171/// - `default_code = "..."`: make the field optional, defaulting to the expression `...`. Note that
172///   you need to enclose it in quotes, which allows you to use it together with other custom
173///   derive proc-macro crates that complain about "expected literal". Note that if `...` contains
174///   a string, you can use raw string literals to avoid escaping the double quotes - e.g.
175///   `#[builder(default_code = r#""default text".to_owned()"#)]`.
176///
177/// - `via_mutators`: initialize the field when constructing the builder, useful in combination
178///   with [mutators](#mutators).
179///
180/// - `via_mutators = ...` or `via_mutators(init = ...)`: initialies the field with the expression `...`
181///   when constructing the builder, useful in combination with [mutators](#mutators).
182///
183/// - `mutators(...)` takes functions, that can mutate fields inside of the builder.
184///   Mutators specified on a field, mark this field as required, see [mutators](#mutators) for details.
185///
186/// - `setter(...)`: settings for the field setters. The following values are permitted inside:
187///
188///   - `doc = "..."`: sets the documentation for the field's setter on the builder type. This will be
189///     of no value unless you enable docs for the builder type with `#[builder(doc)]` or similar on
190///     the type.
191///
192///   - `skip`: do not define a method on the builder for this field. This requires that a default
193///     be set.
194///
195///   - `into`: automatically convert the argument of the setter method to the type of the field.
196///     Note that this conversion interferes with Rust's type inference and integer literal
197///     detection, so this may reduce ergonomics if the field type is generic or an unsigned integer.
198///
199///   - `strip_option`: for `Option<...>` fields only, this makes the setter wrap its argument with
200///     `Some(...)`, relieving the caller from having to do this. Note that with this setting on
201///     one cannot set the field to `None` with the setter - so the only way to get it to be `None`
202///     is by using `#[builder(default)]` and not calling the field's setter.
203///
204///   - `strip_option(fallback = field_opt)`: for `Option<...>` fields only. As above this
205///     still wraps the argument with `Some(...)`. The name given to the fallback method adds
206///     another method to the builder without wrapping the argument in `Some`. You can now call
207///     `field_opt(Some(...))` instead of `field(...)`.
208///
209///     The `setter(strip_option)` attribute supports several `field_defaults` features:
210///
211///     - `ignore_invalid`: Skip stripping for non-Option fields instead of causing a compile error
212///     - `fallback_prefix`: Add a prefix to every fallback method name
213///     - `fallback_suffix`: Add a suffix to every fallback method name
214///
215///     Example:
216///
217///     ```
218///     use typed_builder::TypedBuilder;
219///
220///     #[derive(TypedBuilder)]
221///     #[builder(field_defaults(setter(strip_option(
222///         ignore_invalid,
223///         fallback_prefix = "opt_",
224///         fallback_suffix = "_val"
225///     ))))]
226///     struct Foo {
227///         x: Option<i32>,  // Can use .x(42) or .opt_x_val(None)
228///         y: i32,          // Uses .y(42) only since it's not an Option
229///     }
230///     ```
231///
232///   - `strip_bool`: for `bool` fields only, this makes the setter receive no arguments and simply
233///     set the field's value to `true`. When used, the `default` is automatically set to `false`.
234///
235///   - `strip_bool(fallback = field_bool)`: for `bool` fields only. As above this allows passing
236///     the boolean value. The name given to the fallback method adds another method to the builder
237///     without where the bool value can be specified.
238///
239///   - `transform = |param1: Type1, param2: Type2 ...| expr`: this makes the setter accept
240///     `param1: Type1, param2: Type2 ...` instead of the field type itself. The parameters are
241///     transformed into the field type using the expression `expr`. The transformation is performed
242///     when the setter is called. `transform` can also be provided in full `fn` syntax,
243///     to allow custom lifetimes, a generic and a where clause.
244///     Example:
245///     ```rust
246///     #[builder(
247///         setter(
248///             fn transform<'a, M>(value: impl IntoValue<'a, String, M>) -> String
249///             where
250///                 M: 'a,
251///             {
252///                 value.into_value()
253///             },
254///         )
255///     )]
256///     ```
257///
258///   - `prefix = "..."` prepends the setter method with the specified prefix. For example, setting
259///     `prefix = "with_"` results in setters like `with_x` or `with_y`. This option is combinable
260///     with `suffix = "..."`.
261///
262///   - `suffix = "..."` appends the setter method with the specified suffix. For example, setting
263///     `suffix = "_value"` results in setters like `x_value` or `y_value`. This option is combinable
264///     with `prefix = "..."`.
265///
266///   - `mutable_during_default_resolution`: when expressions in `default = ...` field attributes
267///     are evaluated, this field will be mutable, allowing earlier-defined fields to be mutated by
268///     later-defined fields.
269///     **Warning** - Use this feature with care! If the field that mutates the previous field in
270///     its `default` expression is set via a setter, that mutation will not happen.
271///
272/// # Mutators
273/// Set fields can be mutated using mutators, these can be defind via `mutators(...)`.
274///
275/// Fields annotated with `#[builder(via_mutators)]` are always available to mutators. Additional fields,
276/// that the mutator accesses need to be delcared using `#[mutator(requires = [field1, field2, ...])]`.
277/// The mutator will only be availible to call when they are set.
278///
279/// Mutators on a field, result in them automatically making the field required, i.e., it needs to be
280/// marked as `via_mutators`, or its setter be called. Appart from that, they behave identically.
281///
282/// ```
283/// use typed_builder::TypedBuilder;
284///
285/// #[derive(PartialEq, Debug, TypedBuilder)]
286/// #[builder(mutators(
287///     // Mutator has only acces to fields marked as `via_mutators`.
288///     fn inc_a(&mut self, a: i32){
289///         self.a += a;
290///     }
291///     // Mutator has access to `x` additionally.
292///     #[mutator(requires = [x])]
293///     fn x_into_b(&mut self) {
294///         self.b.push(self.x)
295///     }
296/// ))]
297/// struct Struct {
298///     // Does not require explicit `requires = [x]`, as the field
299///     // the mutator is specifed on, is required implicitly.
300///     #[builder(mutators(
301///         fn x_into_b_field(self) {
302///             self.b.push(self.x)
303///         }
304///     ))]
305///     x: i32,
306///     #[builder(via_mutators(init = 1))]
307///     a: i32,
308///     #[builder(via_mutators)]
309///     b: Vec<i32>
310/// }
311///
312/// // Mutators do not enforce only being called once
313/// assert_eq!(
314///     Struct::builder().x(2).x_into_b().x_into_b().x_into_b_field().inc_a(2).build(),
315///     Struct {x: 2, a: 3, b: vec![2, 2, 2]});
316/// ```
317pub use typed_builder_macro::TypedBuilder;
318
319#[doc(hidden)]
320pub trait NextFieldDefault<TypedBuilderExistingFields> {
321    type Output;
322
323    fn resolve(input: TypedBuilderExistingFields) -> Self::Output;
324}
325
326// It'd be nice for the compilation tests to live in tests/ with the rest, but short of pulling in
327// some other test runner for that purpose (e.g. compiletest_rs), rustdoc compile_fail in this
328// crate is all we can use.
329
330#[doc(hidden)]
331/// When a property is non-default, you can't ignore it:
332///
333/// ```compile_fail
334/// use typed_builder::TypedBuilder;
335///
336/// #[derive(TypedBuilder)]
337/// struct Foo {
338///     x: i8,
339/// }
340///
341/// let _ = Foo::builder().build();
342/// ```
343///
344/// When a property is skipped, you can't set it:
345/// (“method `y` not found for this”)
346///
347/// ```compile_fail
348/// use typed_builder::TypedBuilder;
349///
350/// #[derive(PartialEq, TypedBuilder)]
351/// struct Foo {
352///     #[builder(default, setter(skip))]
353///     y: i8,
354/// }
355///
356/// let _ = Foo::builder().y(1i8).build();
357/// ```
358///
359/// But you can build a record:
360///
361/// ```
362/// use typed_builder::TypedBuilder;
363///
364/// #[derive(PartialEq, TypedBuilder)]
365/// struct Foo {
366///     #[builder(default, setter(skip))]
367///     y: i8,
368/// }
369///
370/// let _ = Foo::builder().build();
371/// ```
372///
373/// `skip` without `default` is disallowed:
374/// (“error: #[builder(skip)] must be accompanied by default”)
375///
376/// ```compile_fail
377/// use typed_builder::TypedBuilder;
378///
379/// #[derive(PartialEq, TypedBuilder)]
380/// struct Foo {
381///     #[builder(setter(skip))]
382///     y: i8,
383/// }
384/// ```
385///
386/// `clone` does not work if non-Clone fields have already been set
387///
388/// ```compile_fail
389/// use typed_builder::TypedBuilder;
390///
391/// #[derive(Default)]
392/// struct Uncloneable;
393///
394/// #[derive(TypedBuilder)]
395/// struct Foo {
396///     x: Uncloneable,
397///     y: i32,
398/// }
399///
400/// let _ = Foo::builder().x(Uncloneable).clone();
401/// ```
402///
403/// Same, but with generics
404///
405/// ```compile_fail
406/// use typed_builder::TypedBuilder;
407///
408/// #[derive(Default)]
409/// struct Uncloneable;
410///
411/// #[derive(TypedBuilder)]
412/// struct Foo<T> {
413///     x: T,
414///     y: i32,
415/// }
416///
417/// let _ = Foo::builder().x(Uncloneable).clone();
418/// ```
419///
420/// Handling deprecated fields:
421///
422/// ```compile_fail
423/// use typed_builder::TypedBuilder;
424///
425/// #[derive(TypedBuilder)]
426/// struct Foo {
427///     #[deprecated = "Don't use this!"]
428///     #[allow(dead_code)]
429///     value: i32,
430/// }
431///
432/// #[deny(deprecated)]
433/// Foo::builder().value(42).build();
434/// ```
435///
436/// Handling invalid property for `strip_option`
437///
438/// ```compile_fail
439/// use typed_builder::TypedBuilder;
440///
441/// #[derive(TypedBuilder)]
442/// struct Foo {
443///     #[builder(setter(strip_option(invalid_field = "should_fail")))]
444///     value: Option<i32>,
445/// }
446/// ```
447///
448/// Handling multiple properties for `strip_option`
449///
450/// ```compile_fail
451/// use typed_builder::TypedBuilder;
452///
453/// #[derive(TypedBuilder)]
454/// struct Foo {
455///     #[builder(setter(strip_option(fallback = value_opt, fallback = value_opt2)))]
456///     value: Option<i32>,
457/// }
458/// ```
459///
460/// Handling alternative properties for `strip_option`
461///
462/// ```compile_fail
463/// use typed_builder::TypedBuilder;
464///
465/// #[derive(TypedBuilder)]
466/// struct Foo {
467///     #[builder(setter(strip_option(type = value_opt, fallback = value_opt2)))]
468///     value: Option<i32>,
469/// }
470/// ```
471///
472/// Handling invalid property for `strip_bool`
473///
474/// ```compile_fail
475/// use typed_builder::TypedBuilder;
476///
477/// #[derive(TypedBuilder)]
478/// struct Foo {
479///     #[builder(setter(strip_bool(invalid_field = should_fail)))]
480///     value: bool,
481/// }
482/// ```
483///
484/// Handling multiple propertes for `strip_bool`
485///
486/// ```compile_fail
487/// use typed_builder::TypedBuilder;
488///
489/// #[derive(TypedBuilder)]
490/// struct Foo {
491///     #[builder(setter(strip_bool(fallback = value_bool, fallback = value_bool2)))]
492///     value: bool,
493/// }
494/// ```
495///
496/// Handling alternative propertes for `strip_bool`
497///
498/// ```compile_fail
499/// use typed_builder::TypedBuilder;
500///
501/// #[derive(TypedBuilder)]
502/// struct Foo {
503///     #[builder(setter(strip_bool(invalid = value_bool, fallback = value_bool2)))]
504///     value: bool,
505/// }
506/// ```
507fn _compile_fail_tests() {}