former 2.22.0

A flexible implementation of the Builder pattern supporting nested builders and collection-specific subformers. Simplify the construction of complex objects.
Documentation
# Technical Specification: The `former` Derive Macro

### 1. Introduction & Core Concepts

*   **1.1. Problem Solved:** The `former` derive macro simplifies the implementation of the Builder pattern in Rust. It automates the generation of fluent, readable, and maintainable APIs for object initialization, reducing boilerplate code for complex `struct` and `enum` types.

*   **1.2. Guiding Principles:**
    *   **Clarity over Brevity:** The generated code and public APIs should be easy to understand and predictable.
    *   **Composition over Configuration:** Favor nested builders (subformers) for complex data structures to maintain a clear, hierarchical construction flow.
    *   **Convention over Configuration:** Provide sensible defaults for common patterns (e.g., handling of `Option<T>`, default collection formers) while allowing explicit overrides for customization.
    *   **Dependencies: Prefer `macro_tools`:** The macro's internal implementation **must** prefer the abstractions provided by the `macro_tools` crate over direct usage of `syn`, `quote`, and `proc-macro2`.

*   **1.3. Key Terminology (Ubiquitous Language):**
    *   **Former:** The builder struct generated by the `#[derive(Former)]` macro (e.g., `MyStructFormer`).
    *   **Storage:** An internal, temporary struct (`...FormerStorage`) that holds the intermediate state of the object being built.
    *   **Definition:** A configuration struct (`...FormerDefinition`) that defines the types and `End` condition for a forming process.
    *   **Subformer:** A `Former` instance used to build a part of a larger object.

### 2. Core Behavioral Specification

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.

#### 2.1. Enum Variant Constructor Logic

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:

| Rule | Variant Structure | Attribute(s) | Generated Constructor Behavior |
| :--- | :--- | :--- | :--- |
| **1a** | Unit: `V` | `#[scalar]` or Default | Direct constructor: `Enum::v() -> Enum` |
| **1b** | Tuple: `V()` | `#[scalar]` or Default | Direct constructor: `Enum::v() -> Enum` |
| **1c** | Struct: `V {}` | `#[scalar]` | Direct constructor: `Enum::v() -> Enum` |
| **1d** | Tuple: `V(T1)` | `#[scalar]` | Scalar constructor: `Enum::v(T1) -> Enum` |
| **1e** | Struct: `V {f1:T1}` | `#[scalar]` | Scalar constructor: `Enum::v{f1:T1} -> Enum` |
| **1f** | Tuple: `V(T1, T2)` | `#[scalar]` | Scalar constructor: `Enum::v(T1, T2) -> Enum` |
| **1g** | Struct: `V {f1:T1, f2:T2}` | `#[scalar]` | Scalar constructor: `Enum::v{f1:T1, f2:T2} -> Enum` |
| **2a** | Unit: `V` | `#[subform_scalar]` | **Compile Error** |
| **2b** | Tuple: `V()` | `#[subform_scalar]` | **Compile Error** |
| **2c** | Struct: `V {}` | `#[subform_scalar]` | **Compile Error** |
| **2d** | Tuple: `V(T1)` | `#[subform_scalar]` or Default | Subformer for inner type: `Enum::v() -> T1::Former` |
| **2e** | Struct: `V {f1:T1}` | `#[subform_scalar]` or Default | Implicit variant former: `Enum::v() -> VFormer` |
| **2f** | Tuple: `V(T1, T2)` | `#[subform_scalar]` | **Compile Error** |
| **2g** | Struct: `V {f1:T1, f2:T2}` | `#[subform_scalar]` or Default | Implicit variant former: `Enum::v() -> VFormer` |
| **3c** | Struct: `V {}` | Default | **Compile Error** (Requires `#[scalar]`) |
| **3f** | Tuple: `V(T1, T2)` | Default | **Implicit variant former: `Enum::v() -> VFormer`** |

**Note on Rule 3f:** This rule is updated to reflect the implemented and tested behavior. The previous specification incorrectly stated this case would generate a scalar constructor. The actual behavior is to generate a subformer for the variant itself.

#### 2.2. Standalone Constructor Behavior

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 `#[arg_for_constructor]` on its fields:

*   **Rule SC-1 (Full Construction):** If **all** fields of a struct or enum variant are marked with `#[arg_for_constructor]`, the generated standalone constructor will take all fields as arguments and return the final, constructed instance (`Self`).
*   **Rule SC-2 (Partial Construction):** If **some or none** of the fields of a struct or enum variant are marked with `#[arg_for_constructor]`, the generated standalone constructor will take only the marked fields as arguments and return an instance of the `Former` (`...Former`), pre-initialized with those arguments.

#### 2.3. Attribute Reference

The following attributes control the behavior defined in the logic tables above.

##### 2.3.1. Item-Level Attributes

| Attribute | Purpose & Behavior |
| :--- | :--- |
| `#[storage_fields(..)]` | Defines extra fields exclusive to the `...FormerStorage` struct for intermediate calculations. |
| `#[mutator(custom)]` | Disables default `FormerMutator` implementation, requiring a manual `impl` block. |
| `#[perform(fn...)]` | Specifies a method on the original struct to be called by `.perform()` after forming. |
| `#[standalone_constructors]` | Generates top-level constructor functions. |
| `#[debug]` | Prints the macro's generated code to the console at compile time. |

##### 2.3.2. Field-Level / Variant-Level Attributes

| Attribute | Purpose & Behavior |
| :--- | :--- |
| `#[former(default = ...)]` | Provides a default value for a field if its setter is not called. |
| `#[scalar]` | Forces the generation of a simple scalar setter (e.g., `.field(value)`). |
| `#[subform_scalar]` | Generates a method returning a subformer for a nested struct. The field's type must also derive `Former`. |
| `#[subform_collection]` | Generates a method returning a specialized collection subformer (e.g., `VectorFormer`). |
| `#[subform_entry]` | Generates a method returning a subformer for a single entry of a collection. |
| `#[arg_for_constructor]` | Marks a field as a required argument for a `#[standalone_constructors]` function. |

##### 2.3.3. Attribute Precedence and Interaction Rules

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)]`.
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.
3.  **Setter Disabling:** `setter = false` on any attribute (`scalar`, `subform_*`) will prevent the generation of that specific user-facing setter method. Internal helper methods (e.g., `_field_subform_entry()`) are still generated to allow for manual implementation of custom setters.
4.  **`#[former(default = ...)]`:** This attribute is independent and can be combined with any setter type. It provides a fallback value if a field's setter is never called.

### 3. Generated Code Architecture

The `#[derive(Former)]` macro generates a consistent set of components to implement the behavior defined in Section 2.

*   **`TFormer` (The Former)**
    *   **Purpose:** The public-facing builder.
    *   **Key Components:** A `storage` field, an `on_end` field, setter methods, and a `.form()` method.

*   **`TFormerStorage` (The Storage)**
    *   **Purpose:** Internal state container.
    *   **Key Components:** A public, `Option`-wrapped field for each field in `T` and any `#[storage_fields]`.

*   **`TFormerDefinition` & `TFormerDefinitionTypes` (The Definition)**
    *   **Purpose:** To make the forming process generic and customizable.
    *   **Key Associated Types:** `Storage`, `Context`, `Formed`, `End`.

### 4. Diagnostics & Debugging

*   **Error Handling Strategy:** The macro must produce clear, concise, and actionable compile-time errors. Errors must be associated with the specific `span` of the code that caused the issue. The `trybuild` crate must be used to create a suite of compile-fail tests to verify error-handling behavior.

*   **Debug Attribute Requirements:** Following the design principle "Proc Macros: Must Implement a 'debug' Attribute", the `#[debug]` item-level attribute must be provided with comprehensive debugging capabilities.

#### 4.1. Debug Attribute Specification

**Attribute Usage:**
```rust
// Standalone debug attribute
#[derive(Former)]
#[debug]  // <-- Enables comprehensive debug output
pub struct MyStruct { field: String }

// Within #[former(...)] container
#[derive(Former)]
#[former(debug, standalone_constructors)]  // <-- Debug with other attributes
pub struct MyStruct { field: String }
```

**Debug Output Requirements:**
When `#[debug]` is present and the `former_diagnostics_print_generated` feature is enabled, the macro must provide detailed information in four phases:

1. **Input Analysis Phase**:
   - Target type information (name, kind, visibility)
   - Generic parameters analysis (lifetimes, types, consts, where clauses)
   - Field/variant analysis with types and attributes
   - Complete attribute configuration breakdown

2. **Generic Classification Phase**:
   - Classification results (lifetime-only, type-only, mixed, empty)
   - Generated generic components (impl_generics, ty_generics, where_clause)
   - Strategy explanation for code generation decisions

3. **Generated Components Analysis Phase**:
   - Core component breakdown (FormerStorage, FormerDefinition, Former, etc.)
   - Trait implementation overview
   - Formation process workflow explanation
   - Attribute-driven customizations impact

4. **Complete Generated Code Phase**:
   - Final TokenStream output for compilation
   - Integration points with existing code

**Feature Flag Integration:**
Debug output must be gated behind the `former_diagnostics_print_generated` feature flag to ensure zero impact on normal compilation.

**Development Workflow Integration:**
- Zero runtime cost (analysis only during compilation)
- Conditional compilation (debug code only with feature flag)
- IDE-friendly output format
- CI/CD pipeline compatibility

### 5. Lifecycle & Evolution

*   **Versioning Strategy:** The `former` crate must adhere to Semantic Versioning 2.0.0.
*   **Deprecation Strategy:** Features or attributes planned for removal must first be marked as deprecated via `#[deprecated]` for at least one minor release cycle before being removed in a subsequent major version.

### 6. Meta-Requirements
*   **Ubiquitous Language:** All terms defined in the `Key Terminology` section must be used consistently.
*   **Naming Conventions:** All generated asset names must use `snake_case`. Generated functions must follow a `noun_verb` pattern.
*   **Single Source of Truth:** The Git repository is the single source of truth for all project artifacts.

### 7. Deliverables
*   `specification.md`: This document.
*   `spec_addendum.md`: A companion document for implementation-specific details.

### 8. Conformance Check Procedure
1.  **Run Full Test Suite:** Execute `cargo test --workspace`.
2.  **Check Linter:** Execute `cargo clippy --workspace --all-targets -- -D warnings`.
3.  **Review Attribute Coverage:** Manually verify that every rule in the logic tables has a corresponding passing test.
4.  **Review Documentation:** Manually verify that the `Readme.md` and `advanced.md` documents are consistent with this specification.

***

# Specification Addendum

### Purpose
This document is a companion to the main `specification.md`. It is intended to be completed by the **Developer** during the implementation of the `former` macro. While the main specification defines the "what" and "why" of the macro's public contract, this addendum captures the "how" of the final implementation.

### Instructions for the Developer
As you implement or modify the `former_meta` crate, please fill out the sections below with the relevant details. This creates a crucial record for future maintenance, debugging, and onboarding.

---

### Internal Module Overview
*A high-level description of the key modules within the `former_meta` crate and their responsibilities.*

| Module | Responsibility |
| :--- | :--- |
| `derive_former` | Top-level entry point for the `#[derive(Former)]` macro. Dispatches to struct or enum handlers. |
| `derive_former::former_struct` | Contains the primary logic for generating all code components for `struct`s. |
| `derive_former::former_enum` | Contains the primary dispatch logic for `enum`s, routing to specific variant handlers based on the rules in the specification. |
| `derive_former::former_enum::*` | Individual handler modules for each combination of enum variant type and attribute (e.g., `unit_variant_handler`, `tuple_single_field_scalar`). |
| `derive_former::field_attrs` | Defines and parses all field-level and variant-level attributes (e.g., `#[scalar]`). |
| `derive_former::struct_attrs` | Defines and parses all item-level attributes (e.g., `#[storage_fields]`). |

### Key Internal Data Structures
*List the primary internal-only structs or enums used during the macro expansion process and their purpose.*

| Struct/Enum | Crate | Purpose |
| :--- | :--- | :--- |
| `ItemAttributes` | `former_meta` | Holds the parsed attributes from the top-level `struct` or `enum`. |
| `FieldAttributes` | `former_meta` | Holds the parsed attributes for a single `struct` field or `enum` variant. |
| `FormerField` | `former_meta` | A unified representation of a field, combining its `syn::Field` data with parsed `FieldAttributes`. |
| `EnumVariantHandlerContext` | `former_meta` | A context object passed to enum variant handlers, containing all necessary information for code generation (AST nodes, attributes, generics, etc.). |

### Testing Strategy
*A description of the testing methodology for the macro.*

-   **UI / Snapshot Testing (`trybuild`):** The `trybuild` crate is used to create a comprehensive suite of compile-fail tests. This ensures that invalid attribute combinations and incorrect usage patterns result in the expected compile-time errors, as defined in the specification.
-   **Manual vs. Derive Comparison:** This is the primary strategy for verifying correctness. For each feature, a three-file pattern is used:
    1.  `_manual.rs`: A file containing a hand-written, correct implementation of the code that the macro *should* generate.
    2.  `_derive.rs`: A file that uses `#[derive(Former)]` on an identical data structure.
    3.  `_only_test.rs`: A file containing only `#[test]` functions that is `include!`d by both the `_manual.rs` and `_derive.rs` files. This guarantees that the exact same assertions are run against both the hand-written and macro-generated implementations, ensuring their behavior is identical.

### Finalized Library & Tool Versions
*List the critical libraries, frameworks, or tools used and their exact locked versions from `Cargo.lock`.*

-   `rustc`: `1.78.0`
-   `macro_tools`: `0.15.0`
-   `convert_case`: `0.6.0`

---

## Development Best Practices and Common Pitfalls

*This section captures critical knowledge gained during implementation to prevent regression and maintain code quality.*

### Critical Development Pitfalls ⚠️

#### 1. Test Verification Trap
**Issue**: Assuming tests are fixed without proper compilation verification
- **Symptom**: Claiming tests work when they have compilation errors
- **Prevention**: Always run `cargo test --all-features --lib test_name --no-run` before marking fixes complete
- **Resolution**: Establish mandatory verification checkpoints in development workflow

#### 2. Commented-Out Derive Attributes 
**Issue**: Tests appear blocked but just have commented `#[derive(Former)]` attributes
- **Detection**: Search for `// #[derive.*Former` patterns in test files
- **Resolution**: Uncomment derive attributes (90% of "blocked" test issues)
- **Prevention**: Use feature flags instead of commenting out derives during debugging

#### 3. Stale BLOCKED Comments
**Issue**: Comments claiming tests are blocked when they actually work with current macro
- **Detection**: Verify every BLOCKED comment by testing actual compilation
- **Resolution**: Update comments immediately when underlying issues are resolved
- **Prevention**: Regular audits of comment accuracy vs. reality

#### 4. Feature Gate Inconsistency
**Issue**: Inconsistent `#[cfg(...)]` patterns across test modules
- **Standard**: Use `#[cfg(any(not(feature = "no_std"), feature = "use_alloc"))]` consistently
- **Prevention**: Create standardized cfg templates for copy-paste
- **Resolution**: Audit and standardize all feature gate patterns

### Development Workflow Best Practices

#### Test Resolution Process
1. **Assessment**: `cargo test --all-features --lib test_name --no-run` (never trust old comments)
2. **Diagnosis**: `grep "// #\[derive.*Former" test_file.rs` (check for commented derives first)
3. **Fix**: Try derive macro first before manual implementation (90% success rate)
4. **Verification**: Compile → Execute → Full suite testing
5. **Documentation**: Update comments and specs immediately

#### Common Resolution Patterns
- **90%**: Simple derive attribute uncommented
- **5%**: Feature gate configuration fixed  
- **5%**: Actual blocking issues requiring architectural changes

#### Manual vs. Derive Decision Tree
```rust
// 1. ALWAYS try derive macro first
#[derive(Debug, PartialEq, Former)]
pub struct MyStruct<T> { ... }

// 2. Only use manual implementation if derive fails with unfixable errors
// (Manual requires 20+ types and trait implementations)
```

### Testing Guidelines

#### Test Isolation Discipline
- Enable and verify ONE test at a time
- Never batch-enable multiple potentially broken tests
- Follow "one test at a time" verification process
- Maintain clear test state isolation

#### Verification Requirements
```bash
# Mandatory verification sequence
cargo test --all-features --lib test_name --no-run  # Compilation
cargo test --all-features --lib test_name           # Execution  
cargo test --all-features --quiet                   # Full suite
```

### Documentation Maintenance

#### Comment Accuracy Requirements
- BLOCKED comments MUST reflect current reality
- Update documentation with every code change
- Document every pitfall encountered for future reference
- Maintain traceability between comments and actual test state

#### Knowledge Preservation Strategy
1. **Immediate Documentation**: Record every resolution as it happens
2. **Pattern Recognition**: Document recurring issue patterns
3. **Prevention Strategies**: Create templates and checklists
4. **Regular Audits**: Monthly review of all BLOCKED/TODO comments

### Architecture Guidelines

#### Derive Macro Capabilities
- Complex lifetime scenarios: Generally supported with proper syntax
- Generic constraints: Usually handled correctly by macro
- Hash+Eq requirements: Check trait bounds for HashMap-like collections
- Feature gate requirements: Must be properly configured for collection tests

#### Manual Implementation Indicators
Manual implementation only needed when:
- Derive macro fails with unfixable fundamental errors (rare)
- Custom forming logic required beyond standard patterns
- Complex HRTB (Higher-Ranked Trait Bounds) scenarios
- Architectural requirements prevent derive macro usage

### Maintenance Checklist

#### Pre-Release Verification
- [ ] All BLOCKED comments verified against actual test compilation
- [ ] Feature gate patterns standardized across all test modules  
- [ ] Documentation updated to reflect current reality
- [ ] Full test suite passes with `cargo test --all-features --quiet`
- [ ] No commented-out derives in production test files

#### Regular Maintenance (Monthly)
- [ ] Audit all BLOCKED/TODO/xxx comments for accuracy
- [ ] Verify "blocked" tests still fail with current macro capabilities
- [ ] Update documentation for any resolved issues
- [ ] Review and update common pitfall documentation

This knowledge base prevents regression and ensures consistent development practices across the `former` crate ecosystem.

### Individual Issue Resolution Catalog

**📋 Comprehensive Documentation**: See `RESOLVED_ISSUES_CATALOG.md` for detailed documentation of **12 specific resolved issues**, each with:
- Exact error messages and root cause analysis
- Specific code changes applied
- Key insights and lessons learned
- Prevention strategies for each issue type
- Cross-issue pattern analysis and meta-insights

This catalog preserves the knowledge from each individual fix to prevent regression and guide future similar issues.