Easy, zero-alloc, ergonomic error-handling with no-std support and optional context heap spilling
Run:
cargo add resext- Or add to your
Cargo.toml:
[dependencies]
resext = "1.4.0"use resext::ctx;
use resext::resext;
use std::io::{Error, ErrorKind};
#[resext]
enum AppError {
Io(Error),
Parse(std::num::ParseIntError),
}
fn read_config(path: &str) -> Res<String> {
let content: String = std::fs::read_to_string(path)
.context(ctx!("Failed to read file: {}", path))?;
if content.is_empty() {
return Err(ResErr::new(
"Content is is empty",
Error::new(ErrorKind::UnexpectedEof, "Data is empty"),
));
}
let value = content
.trim()
.parse::<i32>()
.context(ctx!("Failed to parse config value: {}", &content))?;
if value < 32 {
return Err(ResErr::from_args(
ctx!("Value: {} is less than 32", value),
Error::new(ErrorKind::InvalidData, "Data is less than 32"),
));
}
Ok(content)
}- Type-safe errors - Explicit error enums, no type erasure
- Context chains - Add context to errors as they propagate
- Custom formatting - Configure error display with attributes
- Easy error-handling - Ergonomic, anyhow-like error-handling for seamless
?usage for error-propagation - Zero-alloc - ResExt is allocation free (with optional heap spilling if needed) for restricted environments with inline arrays for context buffers and no boxing (type erasure)
#[resext(
prefix = "ERROR: ",
delimiter = " -> ",
include_variant = true,
alias = ApiResult
)]
enum ApiError {
Network(reqwest::Error),
Database(sqlx::Error),
}MIT license - See LICENSE for details.