waddling-errors-macros 0.7.3

Procedural macros for structured error codes with compile-time validation and taxonomy enforcement
Documentation
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
//! # Sequence Imports Example
//!
//! This example demonstrates how to use the `sequence!` macro with `use` imports
//! to compose sequences from multiple modules or crates.
//!
//! ## Key Features Demonstrated
//!
//! 1. **Importing sequences from other modules** - Use `use` statements within `sequence!`
//! 2. **Mixing imports and local definitions** - Combine external and local sequences
//! 3. **Centralized sequence hub pattern** - Best practice for organizing sequences
//! 4. **Cross-module sequence reuse** - Share common sequences across components
//!
//! ## Running
//!
//! ```bash
//! cargo run --example sequence_imports --features metadata
//! ```

// This example demonstrates importing sequences, so the imports are intentionally used
// within the sequence! macro even though clippy doesn't detect it
#![allow(unused_imports)]

// Compile-time feature check with helpful error message
#[cfg(not(feature = "metadata"))]
compile_error!(
    "\n\n\
    ❌ This example requires the 'metadata' feature!\n\
    \n\
    The diag! macro generates DiagnosticRuntime structs that include\n\
    role-gated fields (hints_runtime_gated, hints_both_gated, etc.)\n\
    which are only compiled when the 'metadata' feature is enabled.\n\
    \n\
    Run this example with:\n\
    \n\
    cargo run --example sequence_imports --features metadata\n\
    \n\
    Or use --all-features to enable everything:\n\
    \n\
    cargo run --example sequence_imports --all-features\n\
    "
);

// ============================================================================
// Module 1: Common Sequences (Shared Library)
// ============================================================================

/// Common sequences that can be reused across multiple modules/crates
mod common_sequences {
    use waddling_errors_macros::sequence;

    sequence! {
        // Input validation sequences (001-010)
        MISSING(1) {
            description: "Required parameter, field, or argument is absent",
            typical_severity: "Error",
            hints: [
                "Check if parameter was provided",
                "Verify required fields are set",
                "Review API documentation for required parameters",
            ],
            related: ["INVALID", "MISMATCH"],
        },

        INVALID(3) {
            description: "Validation failed - data doesn't meet constraints",
            typical_severity: "Error",
            hints: [
                "Review validation rules",
                "Check input format",
                "Verify data constraints",
            ],
            related: ["MISSING", "MISMATCH"],
        },

        MISMATCH(2) {
            description: "Type or value doesn't match expected format",
            typical_severity: "Error",
            hints: [
                "Verify data type",
                "Check value format",
                "Review type conversion logic",
            ],
        },

        // Resource sequences (021-030)
        NOTFOUND(21) {
            description: "Requested resource does not exist",
            typical_severity: "Error",
            hints: [
                "Verify resource identifier",
                "Check if resource was deleted",
                "Confirm resource creation completed",
            ],
            related: ["ALREADYEXISTS"],
        },

        ALREADYEXISTS(22) {
            description: "Resource already exists - creation conflict",
            typical_severity: "Error",
            hints: [
                "Use update instead of create",
                "Check unique constraints",
                "Verify resource wasn't already created",
            ],
            related: ["NOTFOUND", "CONFLICT"],
        },
    }
}

// ============================================================================
// Module 2: Auth-specific Sequences
// ============================================================================

/// Authentication-specific sequences
mod auth_sequences {
    use waddling_errors_macros::sequence;

    sequence! {
        // Import common sequences we need
        use crate::common_sequences::{MISSING, INVALID};

        // Define auth-specific sequences
        DENIED(8) {
            description: "Access denied - insufficient permissions",
            typical_severity: "Error",
            hints: [
                "Verify user permissions",
                "Check authorization token",
                "Review role assignments",
                "Confirm required scopes are granted",
            ],
            related: ["EXPIRED", "REVOKED"],
        },

        AUTH_EXPIRED(18) {
            description: "Token or session has expired",
            typical_severity: "Error",
            hints: [
                "Refresh authentication token",
                "Re-authenticate user",
                "Check token TTL configuration",
            ],
            related: ["DENIED", "REVOKED"],
        },

        REVOKED(19) {
            description: "Token or permission has been revoked",
            typical_severity: "Error",
            hints: [
                "Re-authenticate to obtain new token",
                "Check if user account was suspended",
                "Verify token revocation list",
            ],
            related: ["DENIED", "EXPIRED"],
        },
    }

    // Demonstrate lookup functions
    pub fn demo_lookups() {
        println!("\n🔍 Auth Sequences Lookup Functions:");

        // Look up by number
        if let Some(meta) = lookup_sequence_metadata(8) {
            println!("  Sequence 8: {:?}", meta.description);
        }

        println!("  DENIED constant: {}", DENIED);
        println!("  AUTH_EXPIRED constant: {}", AUTH_EXPIRED);
        println!("  REVOKED constant: {}", REVOKED);

        // Demo lookup functions
        println!("  Lookup by number:");
        if let Some(name) = lookup_sequence_name(8) {
            println!("    Sequence 8 -> '{}'", name);
        }
        if let Some(name) = lookup_sequence_name(18) {
            println!("    Sequence 18 -> '{}'", name);
        }
    }
}

// ============================================================================
// Module 3: Database-specific Sequences
// ============================================================================

/// Database-specific sequences
mod database_sequences {
    use waddling_errors_macros::sequence;

    sequence! {
        // Import common sequences
        use crate::common_sequences::{NOTFOUND, ALREADYEXISTS};

        // Define database-specific sequences
        DB_TIMEOUT(17) {
            description: "Database operation exceeded time limit",
            typical_severity: "Error",
            hints: [
                "Increase query timeout",
                "Optimize database query",
                "Check for table locks",
                "Review query execution plan",
            ],
            related: ["UNAVAILABLE", "EXHAUSTED"],
        },

        CONFLICT(23) {
            description: "Concurrent modification or version conflict",
            typical_severity: "Error",
            hints: [
                "Retry with latest version",
                "Implement optimistic locking",
                "Use SELECT FOR UPDATE",
                "Review transaction isolation level",
            ],
            related: ["ALREADYEXISTS"],
        },

        CORRUPTED(25) {
            description: "Data integrity failure - corruption detected",
            typical_severity: "Critical",
            hints: [
                "Restore from backup",
                "Verify checksums",
                "Check storage health",
                "Run database integrity check",
            ],
        },

        EXHAUSTED(26) {
            description: "Connection pool or quota completely used",
            typical_severity: "Critical",
            hints: [
                "Scale up database connections",
                "Implement connection pooling limits",
                "Review connection leak detection",
                "Monitor connection pool metrics",
            ],
            related: ["TIMEOUT", "UNAVAILABLE"],
        },

        UNAVAILABLE(27) {
            description: "Database temporarily unavailable",
            typical_severity: "Error",
            hints: [
                "Retry after delay with exponential backoff",
                "Check database status",
                "Enable fallback read replicas",
                "Verify network connectivity",
            ],
            related: ["TIMEOUT", "EXHAUSTED"],
        },
    }

    pub fn demo_lookups() {
        println!("\n🔍 Database Sequences Lookup Functions:");
        println!("  DB_TIMEOUT constant: {}", DB_TIMEOUT);
        println!("  CONFLICT constant: {}", CONFLICT);
        println!("  CORRUPTED constant: {}", CORRUPTED);

        // Demo lookup functions
        println!("  Lookup by number:");
        if let Some(name) = lookup_sequence_name(23) {
            println!("    Sequence 23 -> '{}'", name);
        }
    }
}

// ============================================================================
// Module 4: Centralized Sequence Hub (RECOMMENDED PATTERN)
// ============================================================================

/// Centralized sequence hub that re-exports all sequences
///
/// This is the RECOMMENDED pattern for organizing sequences in your application:
/// 1. Define domain-specific sequences in separate modules
/// 2. Import common/shared sequences using `use` statements
/// 3. Re-export everything through a central hub at `crate::sequences`
///
/// This allows `diag!` macro to reference `crate::sequences::NAME` for compile-time validation.
pub mod sequences {
    use waddling_errors_macros::sequence;

    sequence! {
        // Import all sequences from various modules
        use crate::common_sequences::{MISSING, INVALID, MISMATCH, NOTFOUND, ALREADYEXISTS};
        use crate::auth_sequences::{DENIED, AUTH_EXPIRED, REVOKED};
        use crate::database_sequences::{DB_TIMEOUT, CONFLICT, CORRUPTED, EXHAUSTED, UNAVAILABLE};

        // Add hub-specific sequences if needed
        SUCCESS(999) {
            description: "Operation completed successfully",
            typical_severity: "Success",
            hints: [
                "Operation completed without errors",
                "Check result data",
            ],
        },
    }

    pub fn demo_all_sequences() {
        println!("\n📋 All Sequences Available in Hub:");
        println!("\n  Input Validation (001-010):");
        println!("    {} - MISSING", MISSING);
        println!("    {} - MISMATCH", MISMATCH);
        println!("    {} - INVALID", INVALID);

        println!("\n  Authentication (008-020):");
        println!("    {} - DENIED", DENIED);
        println!("    {} - AUTH_EXPIRED", AUTH_EXPIRED);
        println!("    {} - REVOKED", REVOKED);

        println!("\n  Database/Resources (021-030):");
        println!("    {} - NOTFOUND", NOTFOUND);
        println!("    {} - ALREADYEXISTS", ALREADYEXISTS);
        println!("    {} - CONFLICT", CONFLICT);
        println!("    {} - CORRUPTED", CORRUPTED);
        println!("    {} - EXHAUSTED", EXHAUSTED);
        println!("    {} - UNAVAILABLE", UNAVAILABLE);
        println!("    {} - DB_TIMEOUT", DB_TIMEOUT);

        println!("\n  Success (999):");
        println!("    {} - SUCCESS", SUCCESS);

        // Demonstrate lookup functions work on all sequences
        println!("\n  Lookup by number:");
        if let Some(meta) = lookup_sequence_metadata(1) {
            println!("    Seq 1: {}", meta.description.unwrap_or("N/A"));
        }
        if let Some(meta) = lookup_sequence_metadata(8) {
            println!("    Seq 8: {}", meta.description.unwrap_or("N/A"));
        }
        if let Some(meta) = lookup_sequence_metadata(25) {
            println!("    Seq 25: {}", meta.description.unwrap_or("N/A"));
        }

        println!("\n  Lookup by number:");
        if let Some(name) = lookup_sequence_name(1) {
            println!("    Sequence 1 -> '{}'", name);
        }
        if let Some(name) = lookup_sequence_name(8) {
            println!("    Sequence 8 -> '{}'", name);
        }
        if let Some(name) = lookup_sequence_name(25) {
            println!("    Sequence 25 -> '{}'", name);
        }
    }
}

// ============================================================================
// Main Demo
// ============================================================================

fn main() {
    println!("🦆 Sequence Imports Example");
    println!("═══════════════════════════════════════════════════════════");

    println!("\n📚 This example demonstrates:");
    println!("  ✓ Using 'use' statements within sequence! macro");
    println!("  ✓ Importing sequences from other modules");
    println!("  ✓ Mixing imported and locally-defined sequences");
    println!("  ✓ Centralized sequence hub pattern (RECOMMENDED)");

    // Demo individual modules
    auth_sequences::demo_lookups();
    database_sequences::demo_lookups();

    // Demo centralized hub (recommended pattern)
    sequences::demo_all_sequences();

    println!("\n");
    println!("═══════════════════════════════════════════════════════════");
    println!("✨ Key Takeaways:");
    println!("═══════════════════════════════════════════════════════════");
    println!("\n1. SEQUENCE HUB PATTERN (Recommended):");
    println!("   Define sequences in domain modules, re-export via crate::sequences");
    println!("   Example structure:");
    println!("     src/sequences/");
    println!("       common.rs    - Shared sequences (MISSING, INVALID, etc.)");
    println!("       auth.rs      - Auth sequences (DENIED, EXPIRED, etc.)");
    println!("       database.rs  - DB sequences (TIMEOUT, CONFLICT, etc.)");
    println!("       mod.rs       - Hub that imports and re-exports all");
    println!();
    println!("2. IMPORT SYNTAX:");
    println!("   sequence! {{");
    println!("       use crate::common::{{MISSING, INVALID}};");
    println!("       use other_crate::sequences::SHARED;");
    println!("       ");
    println!("       LOCAL(42) {{ description: \"...\", ... }},");
    println!("   }}");
    println!();
    println!("3. COMPILE-TIME VALIDATION:");
    println!("   When diag! references crate::sequences::MISSING, the compiler");
    println!("   will error if MISSING doesn't exist in your sequence hub.");
    println!();
    println!("4. LOOKUP FUNCTIONS:");
    println!("   Each sequence! block generates:");
    println!("     - lookup_sequence_metadata(u16) -> Option<SequenceMetadata>");
    println!("     - lookup_sequence_name(&str) -> Option<u16>");
    println!();
    println!("5. CROSS-CRATE IMPORTS:");
    println!("   You can import sequences from external crates:");
    println!("   sequence! {{");
    println!("       use waddling_errors_common::sequences::{{MISSING, INVALID}};");
    println!("       // Your local sequences...");
    println!("   }}");
    println!();
    println!("✅ Example complete! Check the source code for detailed comments.");
}