waddling-errors 0.7.3

Structured, secure-by-default diagnostic codes for distributed systems with no_std and role-based documentation
Documentation
# Core Library Architecture

This document describes the architecture of `waddling-errors`.

## Overview

The core library has two layers:

1. **Core types** (no_std) - Minimal types for error codes
2. **Doc generator** (std, behind `doc-gen` feature) - Registry + renderer system

---

## Core Types (no_std)

The foundation is intentionally minimal:

```
┌─────────────────────────────────────────────────────┐
│                    Code<C, P>                       │
│  ┌──────────┬───────────┬─────────┬──────────┐      │
│  │ Severity │ Component │ Primary │ Sequence │      │
│  │    E     │   Auth    │  Token  │   001    │      │
│  └──────────┴───────────┴─────────┴──────────┘      │
│                      ↓                              │
│              "E.Auth.Token.001"                     │
└─────────────────────────────────────────────────────┘
```

### Files

| File | Purpose |
|------|---------|
| `severity.rs` | `Severity` enum (E, W, C, B, H, S, K, I, T) |
| `code.rs` | `Code<C, P>` struct - generic over component/primary |
| `traits.rs` | Trait hierarchy for extensibility |

### Trait Hierarchy

```
Level 1 (Required)     Level 2 (Optional)           Level 3 (Optional)
──────────────────     ──────────────────           ──────────────────
ComponentId            ComponentIdDocumented        ErrorMetadata
  └─ as_str()            └─ description()            └─ full doc fields
                         └─ owner()
PrimaryId              PrimaryIdDocumented          FieldMeta
  └─ as_str()            └─ description()            └─ field metadata
```

Users choose the level that fits their needs.

---

## Doc Generator (requires `doc-gen` feature)

A **registry + renderer** pattern for generating error documentation.

### Architecture

```
┌─────────────────────────────────────────────────────────────────────┐
│                          REGISTRATION PHASE                          │
├─────────────────────────────────────────────────────────────────────┤
│                                                                      │
│   ErrorDocBuilder                    DocRegistry                     │
│   ┌──────────────┐                  ┌─────────────────────────┐     │
│   │ .code()      │    register()    │ errors: HashMap         │     │
│   │ .message()   │ ───────────────► │ components: HashMap     │     │
│   │ .hints()     │                  │ primaries: HashMap      │     │
│   │ .tags()      │                  │ sequences: HashMap      │     │
│   │ .build()     │                  └─────────────────────────┘     │
│   └──────────────┘                                                   │
│                                                                      │
└─────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────┐
│                          RENDERING PHASE                            │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│   DocRegistry.render(renderers, role_filter)                        │
│        │                                                            │
│        ├─► filter errors by role (Public/Developer/Internal)        │
│        │                                                            │
│        └─► for each Renderer:                                       │
│                                                                     │
│   ┌─────────────┐  ┌─────────────┐  ┌────────────────────┐          │
│   │JsonRenderer │  │HtmlRenderer │  │ CatalogRenderer    │          │
│   │             │  │             │  │  - Full            │          │
│   │ → .json     │  │ → .html     │  │  - Compact         │          │
│   └─────────────┘  └─────────────┘  │  - Minimal         │          │
│                                     └────────────────────┘          │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘
```

### Files

| File | Purpose |
|------|---------|
| `mod.rs` | Module exports |
| `registry.rs` | `DocRegistry` - central data store |
| `error_builder.rs` | `ErrorDocBuilder` - builder pattern for ErrorDoc |
| `types.rs` | Data structures (`ErrorDoc`, `ComponentMeta`, etc.) |
| `renderer.rs` | `Renderer` trait + `JsonRenderer`, `HtmlRenderer` |
| `catalog_renderer.rs` | `CatalogRenderer` for hash-to-error lookups |
| `render_methods.rs` | `DocRegistry` rendering methods |
| `validation.rs` | Link validation (`see_also` references) |
| `html/` | HTML template, customization, assets |

### Key Types

| Type | Purpose |
|------|---------|
| `DocRegistry` | Central store for all error documentation |
| `ErrorDocBuilder` | Builder for creating `ErrorDoc` instances |
| `ErrorDoc` | Complete documentation for one error code |
| `Renderer` | Trait for output format abstraction |
| `ComponentMeta` | Metadata for a component (Auth, Database, etc.) |
| `PrimaryMeta` | Metadata for a primary category (Token, Query, etc.) |
| `SequenceMeta` | Metadata for a sequence number (001, 017, etc.) |

### Data Flow

```
1. BUILD      ErrorDocBuilder.code("E.Auth.Token.001")
                  .message("Token expired")
                  .hints(["Refresh the token"])
                  .build()
                                                2. REGISTER   DocRegistry.register(error_doc)
                  - Stores in errors HashMap
                  - Updates component/primary counts
                                                3. RENDER     DocRegistry.render([JsonRenderer, HtmlRenderer], Role::Public)
                  - Filters errors by role
                  - Calls each renderer
                  - Writes output files
```

### Renderer Outputs

| Renderer | Output | Use Case |
|----------|--------|----------|
| `JsonRenderer` | `project.json` | API consumption, tooling |
| `HtmlRenderer` | `index.html` | Human-readable docs site |
| `CatalogRenderer` (Full) | `catalog.json` | Hash→error lookup with all fields |
| `CatalogRenderer` (Compact) | `catalog.json` | Production APIs (smaller) |
| `CatalogRenderer` (Minimal) | `catalog.json` | IoT/embedded (smallest) |

### Role-Based Filtering

Errors and their fields can be filtered by visibility:

```
Role::Public    → End users see these
Role::Developer → Developers see these + Public
Role::Internal  → Everyone sees everything
```

Filtering happens at two levels:
1. **Error level**: Entire errors can be role-gated
2. **Field level**: Individual hints/tags can be role-gated

---

## Feature Flags

```
┌─────────────────────────────────────────────────────┐
│                    waddling-errors                  │
├─────────────────────────────────────────────────────┤
│  (default)     │ Core types only (no_std)           │
│  std           │ Standard library support           │
│  alloc         │ Heap allocation without std        │
│  metadata      │ ErrorMetadata trait                │
│  doc-gen       │ Documentation generator (std)      │
│  serde         │ Serialization support              │
│  runtime-hash  │ Runtime hash computation           │
│  macros        │ Re-export waddling-errors-macros   │
└─────────────────────────────────────────────────────┘
```

---

## Extension Points

### Custom Renderers

Implement the `Renderer` trait:

```rust
pub trait Renderer: Send + Sync {
    fn format_name(&self) -> &str;
    fn render(
        &self,
        registry: &DocRegistry,
        errors: &[&ErrorDoc],
        output_path: &Path,
        filter_role: Option<Role>,
    ) -> std::io::Result<()>;
}
```

### Custom Components/Primaries

Implement `ComponentId`/`PrimaryId` traits (Level 1), optionally add documentation traits (Level 2).

---

## Related Documents

- [USAGE_GUIDE.md]USAGE_GUIDE.md - How to use the library
- [FEATURE_FLAGS.md]FEATURE_FLAGS.md - Feature flag details
- [DOC_GENERATION_GUIDE.md]DOC_GENERATION_GUIDE.md - Doc generation walkthrough
- [../DESIGN_RATIONALE.md]../DESIGN_RATIONALE.md - Why decisions were made