standalone/
standalone.rs

1//! Standalone usage of waddling-errors (no external dependencies)
2//!
3//! This example shows how to use waddling-errors WITHOUT any error handling
4//! libraries like thiserror or anyhow. Just pure error codes!
5//!
6//! This is the simplest, most lightweight approach - perfect for:
7//! - Libraries that want minimal dependencies
8//! - no_std environments
9//! - Projects that prefer custom error handling
10//!
11//! Run with: cargo run --example standalone
12
13use waddling_errors::prelude::*;
14
15// ============================================================================
16// Define Error Codes (Zero Runtime Cost - All Const!)
17// ============================================================================
18
19const ERR_INVALID_INPUT: Code = error("INPUT", "INVALID", 1);
20const ERR_NOT_FOUND: Code = error("DATA", "NOTFOUND", 2);
21const WARN_DEPRECATED: Code = warning("API", "DEPR", 1);
22const SUCCESS_COMPLETE: Code = success("TASK", "DONE", 1);
23
24// ============================================================================
25// Simple Error Type (DIY - No External Dependencies)
26// ============================================================================
27
28#[derive(Debug)]
29pub struct AppError {
30    code: Code,
31    message: String,
32}
33
34impl AppError {
35    pub fn new(code: Code, message: impl Into<String>) -> Self {
36        Self {
37            code,
38            message: message.into(),
39        }
40    }
41
42    pub fn code(&self) -> &Code {
43        &self.code
44    }
45}
46
47impl std::fmt::Display for AppError {
48    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
49        write!(f, "[MYAPP.{}] {}", self.code.code(), self.message)
50    }
51}
52
53impl std::error::Error for AppError {}
54
55// ============================================================================
56// Usage Examples
57// ============================================================================
58
59fn validate_age(age: i32) -> Result<(), AppError> {
60    if !(0..=150).contains(&age) {
61        return Err(AppError::new(
62            ERR_INVALID_INPUT,
63            format!("Age {} is out of valid range (0-150)", age),
64        ));
65    }
66    Ok(())
67}
68
69fn find_user(id: u32) -> Result<String, AppError> {
70    // Simulate database lookup
71    if id == 0 {
72        return Err(AppError::new(ERR_NOT_FOUND, "User not found"));
73    }
74    Ok(format!("User #{}", id))
75}
76
77fn process_with_warnings(data: &str) -> Result<String, AppError> {
78    if data.contains("old_api") {
79        // Even with warnings, we can continue - but report it
80        eprintln!("[WARN.{}] Using deprecated API", WARN_DEPRECATED.code());
81    }
82    Ok(data.to_uppercase())
83}
84
85// ============================================================================
86// Alternative: Direct Code Returns (Ultra Minimal)
87// ============================================================================
88
89fn quick_validate(value: i32) -> Result<i32, Code> {
90    if value < 0 {
91        return Err(ERR_INVALID_INPUT);
92    }
93    Ok(value * 2)
94}
95
96// ============================================================================
97// Main Demo
98// ============================================================================
99
100fn main() {
101    println!("šŸ¦† Waddling-Errors Standalone Demo šŸ¦†\n");
102    println!("Zero external dependencies - just pure error codes!\n");
103
104    // Example 1: Custom error type
105    println!("═══════════════════════════════════════════════════");
106    println!("Example 1: Custom Error Type with ErrorCode");
107    println!("═══════════════════════════════════════════════════");
108
109    match validate_age(-5) {
110        Ok(_) => println!("āœ“ Age valid"),
111        Err(e) => {
112            println!("āœ— Error: {}", e);
113            println!("  Code: {}", e.code().code());
114            println!("  Severity: {:?}", e.code().severity());
115        }
116    }
117    println!();
118
119    // Example 2: Not found error
120    println!("═══════════════════════════════════════════════════");
121    println!("Example 2: Data Not Found");
122    println!("═══════════════════════════════════════════════════");
123
124    match find_user(0) {
125        Ok(user) => println!("āœ“ Found: {}", user),
126        Err(e) => {
127            println!("āœ— Error: {}", e);
128            println!("  Code: {}", e.code().code());
129        }
130    }
131    println!();
132
133    // Example 3: Warnings
134    println!("═══════════════════════════════════════════════════");
135    println!("Example 3: Warnings");
136    println!("═══════════════════════════════════════════════════");
137
138    match process_with_warnings("old_api_call()") {
139        Ok(result) => println!("āœ“ Processed (with warnings): {}", result),
140        Err(e) => println!("āœ— Failed: {}", e),
141    }
142    println!();
143
144    // Example 4: Direct ErrorCode returns (ultra minimal)
145    println!("═══════════════════════════════════════════════════");
146    println!("Example 4: Direct ErrorCode Returns (Ultra Minimal)");
147    println!("═══════════════════════════════════════════════════");
148
149    match quick_validate(-10) {
150        Ok(val) => println!("āœ“ Result: {}", val),
151        Err(code) => {
152            println!("āœ— Failed with code: {}", code.code());
153            println!("  Just the error code - no wrapper type needed!");
154        }
155    }
156    println!();
157
158    // Example 5: Success codes
159    println!("═══════════════════════════════════════════════════");
160    println!("Example 5: Success Codes (Active Diagnostic Systems)");
161    println!("═══════════════════════════════════════════════════");
162
163    println!("Task completed!");
164    println!("  Code: {}", SUCCESS_COMPLETE.code());
165    println!("  Positive: {}", SUCCESS_COMPLETE.severity().is_positive());
166    println!("  Active systems can celebrate success! šŸŽ‰");
167    println!();
168
169    // Summary
170    println!("═══════════════════════════════════════════════════");
171    println!("Key Takeaways");
172    println!("═══════════════════════════════════════════════════");
173    println!("āœ“ No external dependencies (thiserror/anyhow optional)");
174    println!("āœ“ Error codes are const fn (zero runtime cost)");
175    println!("āœ“ Works in no_std environments");
176    println!("āœ“ ~500 bytes binary size overhead");
177    println!("āœ“ DIY error types or direct ErrorCode returns");
178    println!("āœ“ Full control over error handling");
179    println!("\nšŸ¦† Pure, lightweight, flexible! šŸ¦†\n");
180}