integration_thiserror/
integration_thiserror.rs1use waddling_errors::{ErrorCode, Severity};
24
25const ERR_INVALID_SALT: ErrorCode = ErrorCode::new(Severity::Error, "CRYPTO", "SALT", 1);
47const ERR_INVALID_KEY: ErrorCode = ErrorCode::new(Severity::Error, "CRYPTO", "KEY", 2);
48const ERR_MAC_FAILED: ErrorCode = ErrorCode::new(Severity::Error, "CRYPTO", "MAC", 3);
49
50const WARN_DEPRECATED: ErrorCode = ErrorCode::new(Severity::Warning, "API", "DEPR", 1);
51
52const CRIT_DATA_CORRUPT: ErrorCode = ErrorCode::new(Severity::Critical, "DATA", "CORRUPT", 1);
53
54#[derive(Debug)]
75pub enum CryptoError {
76 InvalidSaltLength(ErrorCode, usize, usize),
77 InvalidKeyLength(ErrorCode, usize, usize),
78 MacVerificationFailed(ErrorCode),
79}
80
81impl std::fmt::Display for CryptoError {
82 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
83 match self {
84 CryptoError::InvalidSaltLength(code, expected, got) => {
85 write!(
86 f,
87 "[MYLIB.{}] Invalid salt length: expected {} bytes, got {} bytes",
88 code.code(),
89 expected,
90 got
91 )
92 }
93 CryptoError::InvalidKeyLength(code, expected, got) => {
94 write!(
95 f,
96 "[MYLIB.{}] Invalid key length: expected {} bytes, got {} bytes",
97 code.code(),
98 expected,
99 got
100 )
101 }
102 CryptoError::MacVerificationFailed(code) => {
103 write!(f, "[MYLIB.{}] MAC verification failed", code.code())
104 }
105 }
106 }
107}
108
109impl std::error::Error for CryptoError {}
110
111fn validate_salt(salt: &[u8]) -> Result<(), CryptoError> {
116 const EXPECTED_LEN: usize = 32;
117 if salt.len() != EXPECTED_LEN {
118 return Err(CryptoError::InvalidSaltLength(
119 ERR_INVALID_SALT,
120 EXPECTED_LEN,
121 salt.len(),
122 ));
123 }
124 Ok(())
125}
126
127fn validate_key(key: &[u8]) -> Result<(), CryptoError> {
128 const EXPECTED_LEN: usize = 32;
129 if key.len() != EXPECTED_LEN {
130 return Err(CryptoError::InvalidKeyLength(
131 ERR_INVALID_KEY,
132 EXPECTED_LEN,
133 key.len(),
134 ));
135 }
136 Ok(())
137}
138
139fn verify_mac(data: &[u8], mac: &[u8]) -> Result<(), CryptoError> {
140 if data.is_empty() || mac.len() != 32 {
142 return Err(CryptoError::MacVerificationFailed(ERR_MAC_FAILED));
143 }
144 Ok(())
145}
146
147fn main() {
148 println!("š¦ Waddling-Errors + Thiserror Integration Demo š¦\n");
149
150 println!("Example 1: Invalid Salt Length");
152 println!("āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā");
153 let short_salt = [0u8; 16];
154 match validate_salt(&short_salt) {
155 Ok(_) => println!("ā Salt valid"),
156 Err(e) => {
157 println!("ā Error: {}", e);
158 println!(" Error code: E.CRYPTO.SALT.001");
159 println!(" Severity: Error");
160 }
161 }
162 println!();
163
164 println!("Example 2: Invalid Key Length");
166 println!("āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā");
167 let short_key = [0u8; 8];
168 match validate_key(&short_key) {
169 Ok(_) => println!("ā Key valid"),
170 Err(e) => {
171 println!("ā Error: {}", e);
172 println!(" Error code: E.CRYPTO.KEY.002");
173 println!(" Severity: Error");
174 }
175 }
176 println!();
177
178 println!("Example 3: MAC Verification Failed");
180 println!("āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā");
181 let data = b"";
182 let mac = [0u8; 32];
183 match verify_mac(data, &mac) {
184 Ok(_) => println!("ā MAC valid"),
185 Err(e) => {
186 println!("ā Error: {}", e);
187 println!(" Error code: E.CRYPTO.MAC.003");
188 println!(" Severity: Error");
189 }
190 }
191 println!();
192
193 println!("Example 4: Severity Information");
195 println!("āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā");
196 let codes = [
197 (ERR_INVALID_SALT, "Error - Invalid salt"),
198 (WARN_DEPRECATED, "Warning - Deprecated API"),
199 (CRIT_DATA_CORRUPT, "Critical - Data corruption"),
200 ];
201
202 for (code, desc) in &codes {
203 println!("Code: {} | {}", code.code(), desc);
204 println!(" Severity: {:?}", code.severity());
205 println!();
206 }
207
208 println!("Key Takeaways:");
209 println!("āāāāāāāāāāāāāā");
210 println!("ā Error codes are const fn - zero runtime overhead");
211 println!("ā Integrates cleanly with thiserror for professional errors");
212 println!("ā Only ~500 bytes binary size overhead");
213 println!("ā Error codes stable across versions (001, 002, 003...)");
214 println!("ā Severity matrix enables nuanced error handling");
215 println!("\nš¦ Happy error handling! š¦\n");
216}