use assert_matches::assert_matches;
use error_fatality::{Fatality, Split};
use thiserror::Error;
#[derive(Debug, Error, Fatality, Split)]
enum Inner {
#[error("That's it.")]
#[fatal(true)]
GameOver,
#[error("Chuckle")]
#[fatal(false)]
ChuckleOn,
}
#[derive(Debug, Error, Fatality, Split)]
enum Kaboom {
#[fatal(forward)]
#[error(transparent)]
Iffy(Inner),
#[error("Bobo")]
#[fatal(true)]
Bobo,
}
fn game_over() -> Result<(), Kaboom> {
Err(Kaboom::Iffy(Inner::GameOver))
}
fn laughable() -> Result<(), Kaboom> {
Err(Kaboom::Iffy(Inner::ChuckleOn))
}
#[derive(Debug, Error, Fatality, Split)]
#[error(transparent)]
#[fatal(forward)]
struct TransparentStructWrapper {
#[from]
source: Kaboom,
}
#[derive(Debug, Error, Fatality, Split)]
#[error("Struct wrapper")]
#[fatal(forward)]
struct StructWrapper {
source: Kaboom,
other_field: (),
}
impl From<Kaboom> for StructWrapper {
fn from(source: Kaboom) -> Self {
Self {
source,
other_field: (),
}
}
}
#[derive(Debug, Error, Fatality, Split)]
#[error(transparent)]
#[fatal(forward)]
struct TransparentTupleStructWrapper(Kaboom);
#[derive(Debug, Error, Fatality, Split)]
#[error("Tuple struct wrapper")]
#[fatal(forward)]
struct TupleStructWrapper(#[source] Kaboom, ());
impl From<Kaboom> for TupleStructWrapper {
fn from(source: Kaboom) -> Self {
Self(source, ())
}
}
#[derive(Debug, Error, Fatality)]
#[error(transparent)]
#[fatal(forward)]
struct ForwardWrapper(Kaboom);
#[test]
fn main() {
assert!(game_over().unwrap_err().is_fatal());
assert_matches!(
game_over().unwrap_err().split(),
Err(FatalKaboom::Iffy(Inner::GameOver))
);
assert!(!laughable().unwrap_err().is_fatal());
assert_matches!(
laughable().unwrap_err().split(),
Ok(JfyiKaboom::Iffy(Inner::ChuckleOn))
);
assert!(
TransparentStructWrapper::from(game_over().unwrap_err()).is_fatal()
);
assert_matches!(
TransparentStructWrapper::from(game_over().unwrap_err()).split(),
Err(FatalTransparentStructWrapper {
source: FatalKaboom::Iffy(Inner::GameOver)
})
);
assert!(
!TransparentStructWrapper::from(laughable().unwrap_err()).is_fatal()
);
assert_matches!(
TransparentStructWrapper::from(laughable().unwrap_err()).split(),
Ok(JfyiTransparentStructWrapper {
source: JfyiKaboom::Iffy(Inner::ChuckleOn)
})
);
assert!(StructWrapper::from(game_over().unwrap_err()).is_fatal());
assert_matches!(
StructWrapper::from(game_over().unwrap_err()).split(),
Err(FatalStructWrapper {
source: FatalKaboom::Iffy(Inner::GameOver),
other_field: (),
})
);
assert!(!StructWrapper::from(laughable().unwrap_err()).is_fatal());
assert_matches!(
StructWrapper::from(laughable().unwrap_err()).split(),
Ok(JfyiStructWrapper {
source: JfyiKaboom::Iffy(Inner::ChuckleOn),
other_field: (),
})
);
assert!(TransparentTupleStructWrapper(game_over().unwrap_err()).is_fatal());
assert_matches!(
TransparentTupleStructWrapper(game_over().unwrap_err()).split(),
Err(FatalTransparentTupleStructWrapper(FatalKaboom::Iffy(
Inner::GameOver
)))
);
assert!(
!TransparentTupleStructWrapper(laughable().unwrap_err()).is_fatal()
);
assert_matches!(
TransparentTupleStructWrapper(laughable().unwrap_err()).split(),
Ok(JfyiTransparentTupleStructWrapper(JfyiKaboom::Iffy(
Inner::ChuckleOn
)))
);
assert!(TupleStructWrapper::from(game_over().unwrap_err()).is_fatal());
assert_matches!(
TupleStructWrapper::from(game_over().unwrap_err()).split(),
Err(FatalTupleStructWrapper(
FatalKaboom::Iffy(Inner::GameOver),
()
))
);
assert!(!TupleStructWrapper::from(laughable().unwrap_err()).is_fatal());
assert_matches!(
TupleStructWrapper::from(laughable().unwrap_err()).split(),
Ok(JfyiTupleStructWrapper(
JfyiKaboom::Iffy(Inner::ChuckleOn),
()
))
);
assert!(ForwardWrapper(game_over().unwrap_err()).is_fatal());
assert!(!ForwardWrapper(laughable().unwrap_err()).is_fatal());
}