struct_error 0.0.1

Modern, flat, zero-cost error flow based on pure struct errors.
Documentation
use struct_error::{error, match_error, throw, throws, united_error};

#[error("resource not found: {}", self.id)]
pub struct NotFound {
    pub id: u64,
}

#[error("connection timed out after {}ms", self.ms)]
pub struct Timeout {
    pub ms: u64,
}

#[error("I/O error")]
pub struct IoError {
    #[error_source]
    pub inner: std::io::Error,
}

#[united_error(NotFound, Timeout)]
pub struct AppError;

#[throws(NotFound, Timeout)]
pub fn fetch_resource(id: u64) -> String {
    if id == 0 {
        throw!(NotFound { id });
    }
    if id > 100 {
        throw!(Timeout { ms: 5000 });
    }
    format!("resource-{}", id)
}

#[throws(NotFound, Timeout)]
pub fn process(id: u64) -> String {
    let res = fetch_resource(id)?;
    res.to_uppercase()
}

#[throws(AppError)]
pub fn process_united(id: u64) -> String {
    let res = fetch_resource(id)?;
    res.to_uppercase()
}

fn main() {
    for id in [0, 42, 101] {
        let result = process(id);
        match_error!(result {
            Ok(v) => println!("[{}] success: {}", id, v),
            NotFound { id } => println!("[{}] not found: {}", id, id),
            Timeout { ms } => println!("[{}] timeout: {}ms", id, ms),
        });
    }

    println!("--- united error ---");
    match_error!(process_united(0) {
        Ok(v) => println!("success: {}", v),
        NotFound { .. } => println!("not found"),
        Timeout { .. } => println!("timeout"),
    });
}