use n0_error::{Result, StackResultExt, StdResultExt, e, stack_error};
#[stack_error(derive, add_meta, from_sources)]
enum MyError {
#[error("invalid input")]
InvalidInput { source: InvalidInput },
#[error(transparent)]
Io {
#[error(std_err)]
source: std::io::Error,
},
}
#[stack_error(derive, add_meta)]
#[error("wanted {expected} but got {actual}")]
struct InvalidInput {
expected: u32,
actual: u32,
}
fn validate_input(number: u32) -> Result<(), InvalidInput> {
if number != 23 {
Err(e!(InvalidInput {
actual: number,
expected: 23
}))
} else {
Ok(())
}
}
fn fail_io() -> std::io::Result<()> {
Err(std::io::Error::other("io failed"))
}
fn process(number: u32) -> Result<(), MyError> {
validate_input(number)?;
fail_io()?;
fail_io().map_err(|source| e!(MyError::Io, source))?;
Ok(())
}
fn run(number: u32) -> Result<()> {
process(number).context("failed to process input")?;
fail_io().std_context("failed at fail_io")?;
Ok(())
}
fn main() -> Result<()> {
if let Err(err) = run(13) {
println!("{err}");
println!("{err:#}");
println!("{err:?}");
println!("{err:#?}");
}
Ok(())
}
#[stack_error(derive, add_meta)]
#[error("tuple fail ({_0})")]
struct TupleStruct(u32);
#[stack_error(derive, add_meta)]
#[allow(unused)]
enum TupleEnum {
#[error("io failed")]
Io(#[error(source, std_err)] std::io::Error),
}