use waddling_errors::{Code, ComponentId, PrimaryId, Severity};
use waddling_errors::{critical, error, success, warning};
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
enum Component {
Sensor,
Actuator,
Network,
Storage,
}
impl ComponentId for Component {
fn as_str(&self) -> &'static str {
match self {
Component::Sensor => "SENSOR",
Component::Actuator => "ACTUATOR",
Component::Network => "NETWORK",
Component::Storage => "STORAGE",
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
enum Primary {
Timeout,
Invalid,
NotFound,
Corrupted,
}
impl PrimaryId for Primary {
fn as_str(&self) -> &'static str {
match self {
Primary::Timeout => "TIMEOUT",
Primary::Invalid => "INVALID",
Primary::NotFound => "NOTFOUND",
Primary::Corrupted => "CORRUPTED",
}
}
}
const ERR_SENSOR_TIMEOUT: Code<Component, Primary> = error(Component::Sensor, Primary::Timeout, 1);
const ERR_SENSOR_INVALID: Code<Component, Primary> = error(Component::Sensor, Primary::Invalid, 3);
const ERR_ACTUATOR_NOTFOUND: Code<Component, Primary> =
error(Component::Actuator, Primary::NotFound, 21);
const WARN_NETWORK_TIMEOUT: Code<Component, Primary> =
warning(Component::Network, Primary::Timeout, 17);
const CRIT_STORAGE_CORRUPTED: Code<Component, Primary> =
critical(Component::Storage, Primary::Corrupted, 25);
const SUCCESS_OPERATION_COMPLETE: Code<Component, Primary> =
success(Component::Storage, Primary::NotFound, 999);
fn test_error_codes() {
let code = ERR_SENSOR_TIMEOUT;
assert_eq!(code.severity(), Severity::Error);
assert_eq!(code.component(), Component::Sensor);
assert_eq!(code.primary(), Primary::Timeout);
assert_eq!(code.sequence(), 1);
assert_eq!(code.code(), "E.SENSOR.TIMEOUT.001");
}
fn test_component_id() {
let comp = Component::Sensor;
assert_eq!(comp.as_str(), "SENSOR");
}
fn test_primary_id() {
let prim = Primary::Timeout;
assert_eq!(prim.as_str(), "TIMEOUT");
}
fn test_severity() {
let err_sev = ERR_SENSOR_TIMEOUT.severity();
assert_eq!(err_sev, Severity::Error);
assert!(err_sev.is_blocking());
assert!(err_sev.is_negative());
assert!(!err_sev.is_positive());
assert_eq!(err_sev.priority(), 8);
assert_eq!(err_sev.as_char(), 'E');
let warn_sev = WARN_NETWORK_TIMEOUT.severity();
assert_eq!(warn_sev, Severity::Warning);
assert!(!warn_sev.is_blocking());
assert!(warn_sev.is_negative());
assert_eq!(warn_sev.priority(), 5);
assert_eq!(warn_sev.as_char(), 'W');
let crit_sev = CRIT_STORAGE_CORRUPTED.severity();
assert_eq!(crit_sev, Severity::Critical);
assert!(!crit_sev.is_blocking());
assert!(crit_sev.is_negative());
assert_eq!(crit_sev.priority(), 6);
let success_sev = SUCCESS_OPERATION_COMPLETE.severity();
assert_eq!(success_sev, Severity::Success);
assert!(!success_sev.is_blocking());
assert!(!success_sev.is_negative());
assert!(success_sev.is_positive());
assert_eq!(success_sev.priority(), 3);
}
fn test_result_handling() -> Result<(), Code<Component, Primary>> {
fn read_sensor() -> Result<u32, Code<Component, Primary>> {
Err(ERR_SENSOR_TIMEOUT)
}
match read_sensor() {
Ok(_) => Ok(()),
Err(code) => {
assert_eq!(code.component(), Component::Sensor);
assert_eq!(code.primary(), Primary::Timeout);
assert_eq!(code.sequence(), 1);
Err(code)
}
}
}
fn test_copy_clone() {
let err1 = ERR_SENSOR_TIMEOUT;
let err2 = err1; let err3 = err1;
assert_eq!(err1, err2);
assert_eq!(err2, err3);
}
fn test_equality() {
let err1 = ERR_SENSOR_TIMEOUT;
let err2 = error(Component::Sensor, Primary::Timeout, 1);
assert_eq!(err1, err2);
let err3 = ERR_SENSOR_INVALID;
assert_ne!(err1, err3);
}
const CONST_ERROR: Code<Component, Primary> = error(Component::Sensor, Primary::Timeout, 1);
const fn const_fn_test() -> Code<Component, Primary> {
error(Component::Network, Primary::Timeout, 1)
}
fn test_const_fn() {
let _ = CONST_ERROR;
let _ = const_fn_test();
}
fn main() {
println!("🦆 waddling-errors no_std Compatibility Example");
println!("=================================================\n");
println!("💡 KEY INSIGHT: waddling-errors is no_std by default!");
println!(" The core library works WITHOUT the standard library.");
println!(" The 'std' feature is ONLY for doc generation.\n");
println!("📋 Running no_std-compatible tests:\n");
test_error_codes();
println!(" ✓ Error code creation and access");
test_component_id();
println!(" ✓ ComponentId trait");
test_primary_id();
println!(" ✓ PrimaryId trait");
test_severity();
println!(" ✓ Severity levels and all methods");
match test_result_handling() {
Ok(()) => println!(" ✓ Result handling (unexpected)"),
Err(_) => println!(" ✓ Result handling with error codes"),
}
test_copy_clone();
println!(" ✓ Copy and Clone traits");
test_equality();
println!(" ✓ Equality comparison");
test_const_fn();
println!(" ✓ Const fn usage (compile-time evaluation)");
println!("\n📊 Example Error Codes (all work in no_std):\n");
println!(
" {} (priority: {})",
ERR_SENSOR_TIMEOUT.code(),
ERR_SENSOR_TIMEOUT.severity().priority()
);
println!(
" {} (priority: {})",
ERR_SENSOR_INVALID.code(),
ERR_SENSOR_INVALID.severity().priority()
);
println!(
" {} (priority: {})",
ERR_ACTUATOR_NOTFOUND.code(),
ERR_ACTUATOR_NOTFOUND.severity().priority()
);
println!(
" {} (priority: {})",
WARN_NETWORK_TIMEOUT.code(),
WARN_NETWORK_TIMEOUT.severity().priority()
);
println!(
" {} (priority: {})",
CRIT_STORAGE_CORRUPTED.code(),
CRIT_STORAGE_CORRUPTED.severity().priority()
);
println!("\n🎯 What Works in no_std:");
println!(" ✓ Error code creation (const fn, zero cost)");
println!(" ✓ Component and Primary traits");
println!(" ✓ All severity levels with full API");
println!(" ✓ Code formatting without heap allocation");
println!(" ✓ Result<T, Code> error handling");
println!(" ✓ Copy, Clone, PartialEq, Debug traits");
println!(" ✓ All operations are zero-cost abstractions");
println!("\n❌ What Requires 'std' Feature:");
println!(" • Documentation generation (HTML/JSON)");
println!(" • DocRegistry and renderers");
println!(" • Auto-registration system");
println!(" • File I/O for doc output");
println!("\n📦 Build Commands:");
println!(" Regular: cargo run --example no_std_example");
println!(" WASM: cargo build --example no_std_example --target wasm32-unknown-unknown");
println!(" Embedded: cargo build --example no_std_example --target thumbv7em-none-eabihf");
println!("\n📝 Feature Flags:");
println!(" std - Only for doc-gen (NOT for core functionality)");
println!(" metadata - Compile-time metadata (needs paste crate)");
println!(" doc-gen - HTML/JSON generation (requires std)");
println!(" hash - Base62 hash codes (no_std compatible with ahash)");
println!(" serde - Serialization (no_std compatible)");
println!("\n✨ All tests passed! Core library is fully no_std compatible.");
}