errlanes 0.20.3

Four error lanes (Rejected/Denied/Transient/Fatal) carried in the type, not re-derived at every layer
Documentation
//! `Laned::level` is the one public lane→level table. Deliberately not gated
//! on the `tracing` feature: `Level` is errlanes' own type.
use errlanes::{
    Denied, Fail, Fatal, FatalKind, Fault, Lane, Laned, Level, Transient, TransientKind,
};

#[derive(Debug, Clone, errlanes::Rejection)]
enum Levelled {
    #[rejection(code = "DEFAULTED")]
    Defaulted,
    #[rejection(code = "WARNED", level = "warn")]
    Warned,
    #[rejection(code = "QUIET", level = "info")]
    Quiet,
}

#[test]
fn each_lane_has_its_default_level() {
    assert_eq!(Lane::Rejected.level(), Level::Warn);
    assert_eq!(Lane::Denied.level(), Level::Warn);
    assert_eq!(Lane::Transient.level(), Level::Info);
    assert_eq!(Lane::Fatal.level(), Level::Error);
}

#[test]
fn a_built_in_reports_its_lane_default_level() {
    let denied: Fail<Levelled> = Denied::default().into();
    assert_eq!(Laned::level(&denied), Level::Warn);
    let transient: Fail<Levelled> = Transient::new(TransientKind::Deadlock).into();
    assert_eq!(Laned::level(&transient), Level::Info);
    let fatal: Fail<Levelled> = Fatal::new(FatalKind::Invariant).into();
    assert_eq!(Laned::level(&fatal), Level::Error);

    let fault: Fault = Fatal::new(FatalKind::Invariant).into();
    assert_eq!(Laned::level(&fault), Level::Error);
    let fault: Fault = Denied::default().into();
    assert_eq!(Laned::level(&fault), Level::Warn);
}

#[test]
fn a_rejection_overrides_the_lane_default_through_rejection_level() {
    let defaulted: Fail<Levelled> = Fail::Rejected(Levelled::Defaulted);
    assert_eq!(Laned::level(&defaulted), Lane::Rejected.level());

    let quiet: Fail<Levelled> = Fail::Rejected(Levelled::Quiet);
    assert_eq!(Laned::level(&quiet), Level::Info);
    assert_ne!(Laned::level(&quiet), Lane::Rejected.level());
    assert_eq!(quiet.lanes().level(), Level::Info);
}