#![allow(non_upper_case_globals)]
#[cfg(not(feature = "metadata"))]
compile_error!(
"\n\n\
❌ This example requires the 'metadata' feature!\n\
\n\
Run with: cargo run --example test_compile_time_hash --features metadata,hash\n\
"
);
use waddling_errors_macros::{diag, setup};
pub mod components {
use waddling_errors_macros::component;
component! {
pub enum Component {
Auth { docs: "Authentication component" },
Database { docs: "Database component" },
A { docs: "Minimal component" },
Http { docs: "HTTP component" },
}
}
pub use Component::*;
}
pub mod primaries {
use waddling_errors_macros::primary;
primary! {
pub enum Primary {
Token { description: "Token operations" },
Connection { description: "Connection operations" },
B { description: "Minimal primary" },
Request { description: "Request operations" },
}
}
pub use Primary::*;
}
pub mod sequences {
use waddling_errors_macros::sequence;
sequence! {
SEQ001(1) {
description: "Sequence 001",
typical_severity: "Error",
hints: ["Test sequence 001"],
},
SEQ002(2) {
description: "Sequence 002",
typical_severity: "Error",
hints: ["Test sequence 002"],
},
SEQ027(27) {
description: "Sequence 027",
typical_severity: "Warning",
hints: ["Test sequence 027"],
},
}
}
setup! {
components = crate::components,
primaries = crate::primaries,
sequences = crate::sequences,
}
diag! {
strict(component, primary, sequence, naming, duplicates, sequence_values, string_values),
E.Auth.Token.SEQ001: {
message: "Standard error code",
}
}
diag! {
strict(component, primary, sequence, naming, duplicates, sequence_values, string_values),
W.Database.Connection.SEQ027: {
message: "Warning with extended components",
}
}
diag! {
strict(component, primary, sequence, naming, duplicates, sequence_values, string_values),
E.A.B.SEQ001: {
message: "Minimal valid code",
}
}
diag! {
strict(component, primary, sequence, naming, duplicates, sequence_values, string_values),
I.Http.Request.SEQ001: {
message: "Info severity",
}
}
diag! {
strict(component, primary, sequence, naming, duplicates, sequence_values, string_values),
E.Auth.Token.SEQ002: {
message: "Sequential codes produce different hashes",
}
}
fn main() {
println!("🦆 WDP Compact ID Test Vectors - Conformance Test");
println!("====================================================\n");
println!("Testing against official test vectors from:");
println!("wdp-specs/test-vectors/data/compact-ids.json\n");
let mut passed = 0;
let mut failed = 0;
let test_cases = [
(
E_AUTH_TOKEN_SEQ001.code,
E_AUTH_TOKEN_SEQ001_HASH,
"V6a0B",
"basic-001: E.AUTH.TOKEN.001",
),
(
W_DATABASE_CONNECTION_SEQ027.code,
W_DATABASE_CONNECTION_SEQ027_HASH,
"KF52S",
"basic-002: W.DATABASE.CONNECTION.027",
),
(
E_A_B_SEQ001.code,
E_A_B_SEQ001_HASH,
"l3i4I",
"basic-003: E.A.B.001",
),
(
I_HTTP_REQUEST_SEQ001.code,
I_HTTP_REQUEST_SEQ001_HASH,
"iBrs6",
"basic-005: I.HTTP.REQUEST.001",
),
(
E_AUTH_TOKEN_SEQ002.code,
E_AUTH_TOKEN_SEQ002_HASH,
"35Jkp",
"edge-001: E.AUTH.TOKEN.002",
),
];
for (code, compile_time_hash, expected, description) in &test_cases {
print!(" {} ", description);
if compile_time_hash == expected {
println!("✅ PASS");
println!(" Code: {}", code);
println!(" Hash: {} (matches expected)\n", compile_time_hash);
passed += 1;
} else {
println!("❌ FAIL");
println!(" Code: {}", code);
println!(" Expected: {}", expected);
println!(" Got: {}\n", compile_time_hash);
failed += 1;
}
}
{
println!("\n🔍 Verifying runtime hash computation matches compile-time:");
use waddling_errors_hash::compute_hash;
let runtime_tests = [
("E.AUTH.TOKEN.001", "V6a0B", "basic-001"),
("W.DATABASE.CONNECTION.027", "KF52S", "basic-002"),
("E.A.B.001", "l3i4I", "basic-003"),
("I.HTTP.REQUEST.001", "iBrs6", "basic-005"),
("E.AUTH.TOKEN.002", "35Jkp", "edge-001"),
];
for (canonical_code, expected_hash, description) in &runtime_tests {
let runtime_hash = compute_hash(canonical_code);
if &runtime_hash == expected_hash {
println!(" ✅ {} runtime matches", description);
} else {
println!(" ❌ {} runtime mismatch!", description);
println!(" Expected: {}", expected_hash);
println!(" Got: {}", runtime_hash);
failed += 1;
}
}
}
println!("\n====================================================");
println!("Results: {} passed, {} failed", passed, failed);
if failed > 0 {
println!("\n❌ Some tests failed! Hash implementation may not match WDP spec.");
std::process::exit(1);
} else {
println!("\n✅ All test vectors passed! Implementation conforms to WDP spec.");
}
}