#![feature(error_generic_member_access)]
use v_utils_macros::wrap_err;
#[wrap_err]
#[derive(Debug, thiserror::Error)]
#[error("leaf struct error: {msg}")]
pub struct LeafStructError {
msg: String,
}
#[wrap_err]
#[derive(Debug, thiserror::Error)]
#[error("inner: {reason}")]
pub struct InnerError {
reason: String,
}
#[wrap_err]
#[derive(Debug, thiserror::Error)]
pub enum MyError {
#[leaf]
#[error("bad value: {val}")]
BadValue { val: String },
#[leaf]
#[error("unit variant, no user fields")]
UnitVariant,
#[foreign]
Io(std::io::Error),
#[foreign]
#[error("parse failed: {source}")]
Parse(std::num::ParseIntError),
#[own]
Inner(InnerError),
}
#[test]
fn test() {
let e = LeafStructError::new("oops".into());
println!("{e}");
let e2 = MyError::new_bad_value("x".into());
println!("{e2}");
let e3 = MyError::new_unit_variant();
println!("{e3}");
let e4: MyError = std::io::Error::other("disk full").into();
println!("{e4}");
let e5: MyError = "not_a_number".parse::<i32>().unwrap_err().into();
println!("{e5}");
let inner = InnerError::new("oops".into());
let e6: MyError = inner.into();
assert_eq!(e6.to_string(), "inner: oops");
}
fn produces_inner() -> Result<(), InnerError> {
Err(InnerError::new("from inner".into()))
}
#[test]
fn test_own_question_mark() {
let result: Result<(), MyError> = (|| {
produces_inner()?;
Ok(())
})();
assert!(result.is_err());
insta::assert_snapshot!(result.unwrap_err().to_string(), @"inner: from inner");
}