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
Copy file name to clipboardExpand all lines: module/core/former/spec.md
+63-7Lines changed: 63 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -15,14 +15,70 @@
15
15
***Storage:** An internal, temporary struct (`...FormerStorage`) that holds the intermediate state of the object being built.
16
16
***Definition:** A configuration struct (`...FormerDefinition`) that defines the types and `End` condition for a forming process.
17
17
***Subformer:** A `Former` instance used to build a part of a larger object.
18
+
***Target Type Categories:** The fundamental classification of Rust types the macro operates on (Structs vs Enums).
19
+
***Variant Structure Types:** The three categories of enum variant syntax (Unit, Tuple, Named) that determine parsing and generation rules.
20
+
***Behavioral Categories:** The five fundamental groupings that classify all possible Former macro usage patterns based on syntax structure and complexity. These categories drive macro implementation architecture, code generation strategies, and systematic validation (including test organization).
18
21
19
22
### 2. Core Behavioral Specification
20
23
21
24
This section defines the core user-facing contract of the `former` macro. The following logic tables and attribute definitions are the single source of truth for its behavior.
22
25
23
-
#### 2.1. Enum Variant Constructor Logic
26
+
#### 2.1. Target Type Classification
24
27
25
-
The macro generates a static constructor method on the enum for each variant. The type of constructor is determined by the variant's structure and attributes according to the following rules:
28
+
The `former` macro operates on two fundamental **Target Type Categories**, each with distinct behavioral rules and test coverage families:
29
+
30
+
##### 2.1.1. Structural Type Categories
31
+
32
+
***Structs** - Regular Rust structs with named fields (`struct MyStruct { field: T }`)
33
+
***Enums** - Rust enums with variants, subdivided by **Variant Structure Types**:
34
+
35
+
##### 2.1.2. Enum Variant Structure Types
36
+
37
+
The macro classifies enum variants into three **Variant Structure Types** based on their field syntax:
38
+
39
+
***Unit Variants** - No associated data (`Variant`)
40
+
***Tuple Variants** - Positional fields (`Variant(T1, T2)` or `Variant()`)
41
+
***Named Variants** - Named fields (`Variant { field: T }` or `Variant {}`)
42
+
43
+
Each Variant Structure Type has distinct parsing rules, generated code patterns, and behavioral specifications as defined in the rule tables below.
44
+
45
+
##### 2.1.3. Behavioral Categories
46
+
47
+
The macro architecture is organized around five fundamental **Behavioral Categories** that classify all Former usage patterns by syntax structure and complexity:
48
+
49
+
***Struct Formers** - Regular Rust structs with named fields (foundational builder patterns)
50
+
***Unit Variant Formers** - Enum variants with no associated data (simple enum cases)
-**Architectural guidance** for macro implementation organization
75
+
-**API design consistency** across similar usage patterns
76
+
-**Specification completeness** through systematic rule coverage
77
+
-**Quality assurance** via comprehensive test validation families
78
+
79
+
#### 2.2. Enum Variant Constructor Logic
80
+
81
+
The macro generates a static constructor method on the enum for each variant. The type of constructor is determined by the variant's **Variant Structure Type** and attributes according to the following rules:
@@ -53,7 +109,7 @@ The macro generates a static constructor method on the enum for each variant. Th
53
109
- Workaround: Use positional setters or mark variants as `#[scalar]` for direct construction
54
110
55
111
56
-
#### 2.2. Standalone Constructor Behavior
112
+
#### 2.3. Standalone Constructor Behavior
57
113
58
114
When the `#[standalone_constructors]` attribute is applied to an item, the return type of the generated top-level function(s) is determined by the usage of `#[former_ignore]` on its fields:
59
115
@@ -62,11 +118,11 @@ When the `#[standalone_constructors]` attribute is applied to an item, the retur
62
118
63
119
**⚠️ Breaking Change Notice**: This specification represents the current behavior. Previous versions may have implemented different patterns where standalone constructors always returned `Former` instances. Manual implementations following the old pattern need to be updated to match the new specification for consistency.
64
120
65
-
#### 2.3. Attribute Reference
121
+
#### 2.4. Attribute Reference
66
122
67
123
The following attributes control the behavior defined in the logic tables above.
68
124
69
-
##### 2.3.1. Item-Level Attributes
125
+
##### 2.4.1. Item-Level Attributes
70
126
71
127
| Attribute | Purpose & Behavior |
72
128
| :--- | :--- |
@@ -76,7 +132,7 @@ The following attributes control the behavior defined in the logic tables above.
@@ -87,7 +143,7 @@ The following attributes control the behavior defined in the logic tables above.
87
143
|`#[subform_entry]`| Generates a method returning a subformer for a single entry of a collection. |
88
144
|`#[former_ignore]`| Excludes a field from being a parameter in `#[standalone_constructors]` functions. The field will use its default value or remain unset. |
89
145
90
-
##### 2.3.3. Attribute Precedence and Interaction Rules
146
+
##### 2.4.3. Attribute Precedence and Interaction Rules
91
147
92
148
1.**Subform vs. Scalar:** Subform attributes (`#[subform_scalar]`, `#[subform_collection]`, `#[subform_entry]`) take precedence over `#[scalar]`. If both are present, the subform behavior is implemented, and a scalar setter is **not** generated unless explicitly requested via `#[scalar(setter = true)]`.
93
149
2.**Setter Naming:** If a `name` is provided (e.g., `#[scalar(name = new_name)]`), it overrides the default setter name derived from the field's identifier.
0 commit comments