waddling-errors-macros 0.7.3

Procedural macros for structured error codes with compile-time validation and taxonomy enforcement
Documentation
//! Test demonstrating primary! compile-time validation with diag! strict mode
//!
//! This example proves that:
//! 1. primary! generates string constants for each variant
//! 2. diag! strict(primary) validates these at compile-time
//! 3. Invalid primary references would fail compilation
//!
//! ## Running
//!
//! ```bash
//! cargo run --example test_primary_compile_validation --features metadata
//! ```

// Primaries intentionally use CamelCase to match E.Component.Primary.SEQUENCE format
#![allow(non_upper_case_globals)]

// 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 test_primary_compile_validation --features metadata\n\
    \n\
    Or use --all-features to enable everything:\n\
    \n\
    cargo run --example test_primary_compile_validation --all-features\n\
    "
);

use waddling_errors_macros::setup;

setup! {
    components = crate::components,
    primaries = crate::primaries,
    sequences = crate::sequences,
}

// ============================================================================
// Sequences Module
// ============================================================================

pub mod sequences {
    use waddling_errors_macros::sequence;

    sequence! {
        MISSING(1) {
            description: "Required parameter missing",
            typical_severity: "Error",
        },
        INVALID(3) {
            description: "Validation failed",
            typical_severity: "Error",
        },
        DENIED(8) {
            description: "Access denied",
            typical_severity: "Error",
        },
    }
}

// ============================================================================
// Primaries Module (with validation constants)
// ============================================================================

pub mod primaries {
    use waddling_errors_macros::primary;

    primary! {
        pub enum Primary {
            Token {
                docs: "Authentication token errors",
                tags: ["security"],
            },

            Permission {
                docs: "Authorization errors",
                tags: ["security"],
            },

            Validation {
                docs: "Input validation errors",
                tags: ["validation"],
            },
        }
    }
}

// ============================================================================
// Components Module
// ============================================================================

pub mod components {
    use waddling_errors_macros::component;

    component! {
        pub enum Component {
            Auth {
                docs: "Authentication component",
            },
            Api {
                docs: "API component",
            },
        }
    }

    // Re-export for validation
    pub use Component::*;
}

// ============================================================================
// Diagnostics with strict(primary) validation
// ============================================================================

mod diagnostics {
    use waddling_errors_macros::diag;

    // Test 1: No validation (relaxed mode)
    diag! {
        E.Auth.Token.MISSING: {
            message: "Authentication token missing",
            'CR 'Pub hints: ["Include Authorization header"],
        },
    }

    // Test 2: Validate only primary
    diag! {
        strict(primary),

        E.Auth.Token.INVALID: {
            message: "Authentication token invalid",
            'CR 'Pub hints: ["Check token format"],
        },
    }

    // Test 3: Validate sequence and primary
    diag! {
        strict(sequence, primary),

        E.Auth.Permission.DENIED: {
            message: "Permission denied",
            'CR 'Pub hints: ["Verify user permissions"],
        },
    }

    // Test 4: Validate all three
    diag! {
        strict(sequence, primary, component),

        E.Auth.Validation.INVALID: {
            message: "Request validation failed",
            'CR 'Pub hints: ["Check request parameters"],
        },
    }
}

// ============================================================================
// Test that would FAIL if uncommented (primary doesn't exist)
// ============================================================================

/*
mod test_fail {
    use waddling_errors_macros::diag;

    diag! {
        strict(primary),

        E.Auth.NonExistent.MISSING: {
            message: "This should fail - NonExistent primary doesn't exist",
        },
    }
}
*/

fn main() {
    println!("🦆 Primary Compile-Time Validation Test\n");
    println!("===================================================");

    println!("✅ Test 1: Primary constants exist");
    println!("   primaries::Token = {}", primaries::Token);
    println!("   primaries::Permission = {}", primaries::Permission);
    println!("   primaries::Validation = {}", primaries::Validation);
    println!();

    println!("✅ Test 2: Compile-time validation successful");
    println!("   diag! strict(primary) compiled successfully!");
    println!("   - Test relaxed (no validation)");
    println!("   - Test strict(primary)");
    println!("   - Test strict(sequence, primary)");
    println!("   - Test strict(sequence, primary, component)");
    println!();

    println!("===================================================");
    println!("🎉 All tests passed!");
    println!();
    println!("This proves:");
    println!("  • primary! generates BOTH:");
    println!("    - Enum with trait implementations (Primary::Token)");
    println!("    - String constants for validation (TOKEN)");
    println!("  • diag! strict(primary) validates at compile-time");
    println!("  • Invalid primaries would fail compilation");
    println!();
    println!("Uncomment the test_fail module to see compile failure!");
    println!("===================================================");
}