waddling-errors 0.2.0

Ultra-minimal error code standard for the Waddling ecosystem
Documentation

waddling-errors đŸĻ†

Ultra-minimal diagnostic code system

Crates.io Documentation License


Overview

waddling-errors provides a super ergonomic diagnostic code system with consistent error code format generation.

Key Features

  • ✅ Tiny - Modular design, only include what you need
  • ✅ Zero dependencies by default - Optional features for extended functionality
  • ✅ Semantic methods - is_blocking(), is_positive(), priority(), etc.
  • ✅ Visual representation - Emojis (đŸ”Ĩâš ī¸âœ…) and ANSI colors for terminal UIs
  • ✅ Serialization - Optional Serde support for JSON/etc.
  • ✅ no_std compatible - Works in embedded and WASM environments
  • ✅ Const-friendly - Error codes can be defined as constants

Why This Exists

Projects need consistent error code formats for diagnostic tooling integration.

Standard Format

4-Part Format - consistent diagnostic codes:

SEVERITY.COMPONENT.PRIMARY.SEQUENCE → E.CRYPTO.SALT.001

Where SEVERITY can be:

Severity Code Emoji Use Case
Error E ❌ Invalid input, logic errors
Warning W âš ī¸ Deprecated API, edge cases
Critical C đŸ”Ĩ Data corruption, security breach
Blocked B đŸšĢ Deadlock, I/O wait, network down
Success S ✅ Operation succeeded
Completed K âœ”ī¸ Task/phase finished
Info I â„šī¸ Events, milestones, status
Trace T 🔍 Execution traces, probes, timing

Solution: waddling-errors provides a single, minimal, flexible implementation.


Installation

Add to your Cargo.toml:

[dependencies]
# Minimal (no optional features)
waddling-errors = { version = "0.1", default-features = false }

# With base62 hashing
waddling-errors = { version = "0.1", features = ["hash"] }

# With ANSI terminal colors
waddling-errors = { version = "0.1", features = ["ansi-colors"] }

# With emoji support
waddling-errors = { version = "0.1", features = ["emoji"] }

# With Serde serialization
waddling-errors = { version = "0.1", features = ["serde"] }

# All features
waddling-errors = { version = "0.1", features = ["hash", "ansi-colors", "emoji", "serde"] }

Quick Start

use waddling_errors::prelude::*;

// Ultra-clean error definitions
const ERR_SALT: Code = error("CRYPTO", "SALT", 1);
const WARN_DEPRECATED: Code = warning("API", "FUNC", 10);
const SUCCESS_BUILD: Code = success("BUILD", "DONE", 999);

fn validate(data: &[u8]) -> Result<(), Code> {
    if data.is_empty() {
        return Err(ERR_SALT);
    }
    Ok(())
}

fn main() {
    println!("{}", ERR_SALT.code()); // "E.CRYPTO.SALT.001"
    
    // Semantic methods
    println!("Is blocking? {}", ERR_SALT.severity().is_blocking()); // true
    println!("Priority: {}", ERR_SALT.severity().priority()); // 7 (highest)
    
    // Visual representation
    println!("{} Error occurred!", ERR_SALT.severity().emoji()); // "❌ Error occurred!"
}

Usage Patterns

waddling-errors provides multiple API styles - choose what fits your project:

1. Convenience Functions (Recommended)

The cleanest, most ergonomic approach:

use waddling_errors::prelude::*;

// All 8 severity levels
const ERR: Code = error("CRYPTO", "SALT", 1);
const WARN: Code = warning("API", "FUNC", 10);
const CRIT: Code = critical("MEM", "CORRUPT", 23);
const BLOCK: Code = blocked("THREAD", "LOCK", 24);
const SUCCESS: Code = success("BUILD", "DONE", 999);
const COMPLETE: Code = completed("PARSE", "DONE", 999);
const INFO: Code = info("SERVER", "START", 1);
const TRACE: Code = trace("PROBE", "THREAD", 1);

2. Method Style

Object-oriented approach:

use waddling_errors::Code;

const ERR: Code = Code::error("CRYPTO", "SALT", 1);
const WARN: Code = Code::warning("API", "FUNC", 10);

3. Explicit Severity

Full control when needed:

use waddling_errors::{Code, Severity};

const ERR: Code = Code::new(Severity::Error, "CRYPTO", "SALT", 1);

Standalone Usage (No Dependencies)

Return diagnostic codes directly:

use waddling_errors::prelude::*;

const ERR_INVALID_SALT: Code = error("CRYPTO", "SALT", 1);

fn validate(data: &[u8]) -> Result<(), Code> {
    if data.is_empty() {
        return Err(ERR_INVALID_SALT);
    }
    Ok(())
}

// Or wrap in your own error type
#[derive(Debug)]
struct MyError {
    code: Code,
    message: String,
}

impl std::fmt::Display for MyError {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "[MYAPP.{}] {}", self.code.code(), self.message)
    }
}

See examples/standalone.rs for a complete example with no external dependencies.


Error Registry Pattern (Recommended)

For larger projects, create a central error registry:

// errors.rs - Your project's error registry
pub mod errors {
    use waddling_errors::prelude::*;
    
    // Crypto errors (E.CRYPTO.*)
    pub const SALT_MISSING: Code = error("CRYPTO", "SALT", 1);
    pub const KEY_LENGTH: Code = error("CRYPTO", "LENGTH", 2);
    pub const HMAC_INVALID: Code = error("CRYPTO", "HMAC", 3);
    
    // Parser warnings (W.PARSE.*)
    pub const DEPRECATED_SYNTAX: Code = warning("PARSE", "DEPR", 1);
    
    // Build success (S.BUILD.*)
    pub const BUILD_COMPLETE: Code = success("BUILD", "DONE", 999);
}

// Use across your project
use errors::SALT_MISSING;

fn validate_salt(salt: &[u8]) -> Result<(), Code> {
    if salt.len() != 32 {
        return Err(SALT_MISSING);
    }
    Ok(())
}

Benefits:

  • ✅ Centralized error definitions
  • ✅ Easy to document and maintain
  • ✅ Prevents duplicate sequence numbers
  • ✅ IDE autocomplete for all error codes

Semantic Methods

Severity provides rich semantic methods for intelligent error handling:

Categorization

use waddling_errors::Severity;

// Check if execution should stop
if severity.is_blocking() {
    return Err(diagnostic);  // Error or Blocked
}

// Categorize outcomes
if severity.is_positive() {
    println!("✅ Success!");  // Success or Completed
} else if severity.is_negative() {
    println!("âš ī¸ Issue detected");  // Error, Warning, Critical, Blocked
} else {
    println!("â„šī¸ Info");  // Info or Trace
}

Priority Ordering

use waddling_errors::Severity;

// Sort diagnostics by priority (0=lowest, 7=highest)
diagnostics.sort_by_key(|d| d.severity.priority());

// Filter by severity level
let critical_issues: Vec<_> = diagnostics
    .iter()
    .filter(|d| d.severity >= Severity::Warning)
    .collect();

Metadata

use waddling_errors::Severity;

let sev = Severity::Error;
println!("Char: {}", sev.as_char());        // "E"
println!("Name: {}", sev.as_str());         // "Error"
println!("Desc: {}", sev.description());    // "Operation failed"
println!("Priority: {}", sev.priority());   // 7

Visual Representation

Emojis (Feature Flag)

Perfect for modern terminal UIs and logs (requires emoji feature):

use waddling_errors::prelude::*;

println!("{} Build failed!", error("BUILD", "FAIL", 1).severity().emoji());
// Output: ❌ Build failed!

println!("{} Warning: deprecated API", warning("API", "DEPR", 1).severity().emoji());
// Output: âš ī¸ Warning: deprecated API

println!("{} All tests passed!", success("TEST", "PASS", 1).severity().emoji());
// Output: ✅ All tests passed!

Full emoji set:

  • ❌ Error
  • đŸšĢ Blocked
  • đŸ”Ĩ Critical (stands out from warning!)
  • âš ī¸ Warning
  • ✅ Success
  • âœ”ī¸ Completed
  • â„šī¸ Info
  • 🔍 Trace

ANSI Colors (Feature Flag)

Enable with features = ["ansi-colors"]:

use waddling_errors::Severity;

let severity = Severity::Error;
println!(
    "{}Error: Operation failed{}",
    severity.ansi_color(),
    Severity::ANSI_RESET
);
// Output: Error in bold red

// Combine with emojis for maximum clarity
println!(
    "{}{} {}{}",
    severity.ansi_color(),
    severity.emoji(),
    "Critical failure",
    Severity::ANSI_RESET
);
// Output: ❌ Critical failure (in red)

Serialization

Enable with features = ["serde"]:

use waddling_errors::prelude::*;
use serde_json;

let codes = vec![
    error("CRYPTO", "SALT", 1),
    warning("API", "DEPR", 10),
];

// Serialize to JSON
let json = serde_json::to_string(&codes)?;
// [{"severity":"Error","component":"CRYPTO","primary":"SALT","sequence":1}, ...]

// Severities support full round-trip
let severity = Severity::Error;
let json = serde_json::to_string(&severity)?;
let restored: Severity = serde_json::from_str(&json)?;

Sequence Conventions

The Waddling ecosystem uses semantic sequence numbers for common patterns:

Sequence Meaning Example
001 MISSING Required item not provided
002 MISMATCH Values don't match expected type
003 INVALID Format/validation failed
021 NOTFOUND Resource not found
025 CORRUPTED Data corruption detected
031-897 (project) Domain-specific sequences
999 COMPLETE Full completion

Benefits: .001 always means "missing" across ALL Waddling projects.

See docs/SEQUENCE-CONVENTIONS.md for the complete list.


Examples

Run the examples to see features in action:

# Basic emoji support
cargo run --example emoji_demo --features emoji

# ANSI colored terminal output
cargo run --example ansi_colors_demo --features ansi-colors

# Serde serialization
cargo run --example serde_demo --features serde

# Complete severity matrix
cargo run --example severity_matrix

Documentation


License

Dual-licensed under MIT or Apache-2.0.