waddling-errors-macros 0.7.3

Procedural macros for structured error codes with compile-time validation and taxonomy enforcement
Documentation
# Complete System Example - Macro-Based Version

This example demonstrates a realistic web application backend error system using **waddling-errors-macros** for concise, maintainable error definitions.

## 🎯 Key Pattern: Runtime vs Doc-Gen Separation

This example demonstrates the **correct pattern** for separating runtime code from documentation generation:

```
┌─────────────────────────────────────────────────────────────────┐
│  SAME SOURCE CODE → TWO DIFFERENT BINARIES                      │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  cargo run --features metadata,auto-register                    │
│       ↓                                                         │
│  ┌──────────────────────────────────────┐                       │
│  │ RUNTIME BINARY                       │                       │
│  │ • Error codes available              │                       │
│  │ • NO doc-gen code compiled           │                       │
│  │ • Smaller binary size                │                       │
│  │ • Zero doc-gen overhead              │                       │
│  └──────────────────────────────────────┘                       │
│                                                                 │
│  cargo run --features metadata,auto-register,doc-gen            │
│       ↓            -- --generate-docs                           │
│  ┌──────────────────────────────────────┐                       │
│  │ DOC-GEN BINARY                       │                       │
│  │ • Error codes available              │                       │
│  │ • Doc-gen code INCLUDED              │                       │
│  │ • HtmlRenderer, JsonRenderer linked  │                       │
│  │ • Generates HTML/JSON documentation  │                       │
│  └──────────────────────────────────────┘                       │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘
```

### Why This Pattern?

| Concern | Solution |
|---------|----------|
| Production binary size | Doc-gen code not compiled without feature |
| Runtime performance | Zero overhead - unused code isn't there |
| CI/CD flexibility | Generate docs only when needed |
| Developer experience | Same codebase, different outputs |

## Running the Example

### Normal Runtime (no documentation)

```bash
cargo run --example complete_macro_system --features metadata,auto-register
```

This shows:
- Error codes being used at runtime
- Actual hash values and messages
- System statistics

### Documentation Generation

```bash
cargo run --example complete_macro_system \
    --features metadata,auto-register,doc-gen -- --generate-docs
```

This generates:
- `target/doc/WebApp_Backend_(Macros)-pub.html` - Public documentation
- `target/doc/WebApp_Backend_(Macros)-dev.html` - Developer documentation  
- `target/doc/WebApp_Backend_(Macros)-int.html` - Internal documentation
- JSON versions for programmatic access

## How It Works

### 1. Feature-Gated Compilation

```rust
// In main.rs
fn main() {
    if args.contains("--generate-docs") {
        #[cfg(feature = "doc-gen")]
        {
            generate_documentation();  // Only compiled with doc-gen feature
            return;
        }
        #[cfg(not(feature = "doc-gen"))]
        {
            eprintln!("Error: doc-gen feature not enabled");
        }
    }
    
    // Normal runtime - always compiled
    run_application();
}

#[cfg(feature = "doc-gen")]  // Only exists in doc-gen binary
fn generate_documentation() {
    use waddling_errors::doc_generator::{DocRegistry, HtmlRenderer};
    // ... generate docs
}
```

### 2. Auto-Registration via `<formats>`

```rust
diag! {
    <json, html>,  // ← This enables auto-registration!
    
    E.Auth.Token.MISSING: {
        message: "JWT token missing",
        // ...
    },
}
```

The `<json, html>` syntax causes the macro to generate `#[ctor]` code that runs before `main()`, automatically registering all diagnostics.

### 3. Using Error Codes at Runtime

```rust
// Import the generated constants
use components::auth::E_AUTH_TOKEN_MISSING;

// Use them in your code
fn check_auth(request: &Request) -> Result<(), Error> {
    let token = request.header("Authorization")
        .ok_or_else(|| Error::new(
            E_AUTH_TOKEN_MISSING.code,    // "E.Auth.Token.MISSING"
            E_AUTH_TOKEN_MISSING.hash,    // "V6a0B"
            E_AUTH_TOKEN_MISSING.message, // "JWT token missing..."
        ))?;
    // ...
}
```

## CI/CD Integration

### GitHub Actions

```yaml
jobs:
  build:
    steps:
      - name: Build (production)
        run: cargo build --release --features metadata,auto-register
      
      - name: Generate Docs
        run: cargo run --features metadata,auto-register,doc-gen -- --generate-docs
      
      - name: Deploy Docs
        uses: peaceiris/actions-gh-pages@v3
        with:
          publish_dir: ./target/doc
```

### GitLab CI

```yaml
build:
  script:
    - cargo build --release --features metadata,auto-register

generate-docs:
  script:
    - cargo run --features metadata,auto-register,doc-gen -- --generate-docs
  artifacts:
    paths:
      - target/doc/
```

## Project Structure

```
complete_macro_system/
├── main.rs              # Entry point with runtime/doc-gen separation
├── sequences.rs         # Sequence conventions (001=MISSING, etc.)
├── primaries/
│   └── mod.rs          # primary! macro definitions
└── components/
    ├── mod.rs          # Module organization
    ├── auth.rs         # component! + diag! for AUTH
    ├── database.rs     # component! + diag! for DB
    ├── api.rs          # component! + diag! for API
    ├── cache.rs        # component! + diag! for CACHE
    ├── queue.rs        # component! + diag! for QUEUE
    ├── storage.rs      # component! + diag! for STORAGE
    └── navigation.rs   # component! + diag! for NAVIGATION
```

## Components Overview

| Component | Purpose | Example Errors |
|-----------|---------|----------------|
| **Auth** | JWT, OAuth2, RBAC | `E.Auth.Token.MISSING`, `E.Auth.Permission.DENIED` |
| **Db** | PostgreSQL operations | `C.Db.Connection.EXHAUSTED`, `C.Db.Data.CORRUPTED` |
| **Api** | External integrations | `B.Api.RateLimit.EXCEEDED`, `E.Api.Timeout.EXCEEDED` |
| **Cache** | Redis caching | `S.Cache.Data.WARMED`, `W.Cache.Data.STALE` |
| **Queue** | Background jobs | `K.Queue.Data.COMPLETED`, `E.Queue.Timeout.CANCELLED` |
| **Storage** | S3-compatible storage | `K.Storage.Data.UPLOADED`, `C.Storage.Data.CORRUPTED` |
| **Navigation** | Routing & pages | `E.Navigation.Page.NOT_FOUND` (the famous 404!) |

## Macro Syntax Quick Reference

### component! macro

```rust
component! {
    ComponentName {
        docs: "Description",     // Documentation
        examples: ["E.COMP..."], // Example error codes
        tags: ["tag1", "tag2"],  // Searchable tags
    },
}
```

### primary! macro

```rust
primary! {
    PrimaryName {
        docs: "Description",
        examples: ["example1"],
        related: ["Other"],
    },
}
```

### diag! macro

```rust
diag! {
    <json, html>,  // Auto-register for these formats
    
    E.Component.Primary.SEMANTIC: {
        message: "Error message template",
        'CR 'Pub description: "Public description",
        'CR 'Dev hints: ["Developer hints"],
        'CR 'Int hints: ["Internal hints"],
        'R role: "Public",
        'R tags: ["tag1", "tag2"],
        'R related_codes: ["E.Other.Code"],
        'C deprecated: "2.0.0",
        'C see_also: ["E.Replacement.Code"],
    },
}
```

## Learn More

- See `waddling-errors/examples/complete_system` for the manual (non-macro) approach
- See `waddling-errors-macros/docs/` for full macro DSL specification
- See main documentation for error code conventions