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
use impl_builder;
use TokenStream;
use ;
///
/// Derive the [Builder] trait for a struct.
/// Generates a type-level state machine for transitioning between states.
///
/// States correspond to which fields have been set or not.
/// It takes into account the type of the fields.
/// The following types are treated as optional fields:
/// - [BackLink<T>]
/// - [Vec<T>]
/// - [Link<Vec<T>>]
///
/// For example, given the following struct:
/// ```ignore
/// #[derive(Builder, Eq, PartialEq, Debug)]
/// #[enum_wrapper(Op)]
/// struct Foo {
/// a: BackLink<Owner>,
/// b: Vec<BackLink<Owner>>,
/// c: i32,
/// d: Link<Op>,
/// e: Vec<Link<Op>>,
/// f: Link<Vec<Link<Op>>>,
/// }
/// ```
///
/// We now isolate the optional fields:
/// - `a: BackLink<Owner>`
/// - `b: Vec<BackLink<Owner>>`
/// - `e: Vec<Link<Op>>`
/// - `f: Link<Vec<Link<Op>>>`
/// and the required fields:
/// - `c: i32`
/// - `d: Link<Op>`
///
/// We generate an initial state `FooBuilder0` with no fields set,
/// except for the optional fields which are set to their default values.
/// ```ignore
/// let initial_state = [true, true, false, false, true, true];
/// ```
///
/// We then generate a state with each of the required fields set,
/// and every possible combination of those field states.
/// We sort the states by the number of fields set, then by leftmost true bits.
/// ```ignore
/// let states = [
/// // required: req, optional: opt
/// //opt opt req req opt opt // state
/// [true, true, false, false, true, true], // 0
/// [true, true, true, false, true, true], // 1
/// [true, true, false, true, true, true], // 2
/// [true, true, true, true, true, true], // 3
/// ];
/// ```
///
/// We generate a transition table for each state,
/// which maps from the current state to the next state.
/// rows are indexed by the current state,
/// columns by the method thst transitions to the next state.
/// ```ignore
/// let transitions = [
/// /* 0: */ [0, 0, 1, 2, 0, 0],
/// /* 1: */ [1, 1, 1, 3, 1, 1],
/// /* 2: */ [2, 2, 3, 2, 2, 2],
/// /* 3: */ [3, 3, 3, 3, 3, 3],
/// ];
/// ```
///
/// We then generate an implementation for each state,
/// with a method for each field., which transitions to the next state.
/// The [enum_wrapper] attribute is used to automatically wrap the struct in a Link<enum_wrapper>
/// to reduce boilerplate.
/// The only supported [enum_wrapper]s are `Op` and `Root`.
///
/// The following API is generated:
/// ```ignore
/// let a: Link<Owner> = todo!();
/// let b0: Link<Owner> = todo!();
/// let b1: Link<Owner> = todo!();
/// let c = 42;
/// let d: Link<Op> = todo!();
/// let e0: Link<Op> = todo!();
/// let e1: Link<Op> = todo!();
/// let f0: Link<Op> = todo!();
/// let f1: Link<Op> = todo!();
/// let foo = Foo::builder()
/// .a(a.clone())
/// .b(b0.clone())
/// .b(b1.clone())
/// .c(c)
/// .d(d.clone())
/// .e(e0.clone())
/// .e(e1.clone())
/// .f(f0.clone())
/// .f(f1.clone())
/// .build();
/// assert_eq!(foo.borrow().deref(),
/// &Op::Foo(
/// Foo {
/// a: a.clone().into(),
/// b: vec![b0.into(), b1.into()],
/// c,
/// d,
/// e: vec![e0, e1],
/// f: Link::new(vec![f0, f1]),
/// }
/// );
/// ```