assert-rs 0.1.1

An assertion library that uses types and data to fail tests instead of panicking.
Documentation
use super::{AssertInfo, Assertion, Debug, Display};

/// An assertion that will unconditionally fail.
#[must_use = "assertions do not fire unless returned from a test"]
pub struct Fail {
    info: AssertInfo,
}

impl Display for Fail {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        let AssertInfo { file, line, column } = self.info;

        write!(
            f,
            "assertion starting at {file}:{line}:{column} was forced fail"
        )
    }
}

impl Debug for Fail {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        Display::fmt(self, f)
    }
}

impl Fail {
    #[doc(hidden)]
    /// Don't use this constructor. Use [`fail!`] instead.
    pub const fn manual_constructor(file: &'static str, line: u32, column: u32) -> Self {
        Self {
            info: AssertInfo { file, line, column },
        }
    }
}

#[cfg(feature = "std")]
impl std::process::Termination for Fail {
    fn report(self) -> std::process::ExitCode {
        std::process::ExitCode::FAILURE
    }
}

impl Assertion for Fail {
    fn test(&self) -> bool {
        false
    }
}

/// Construct an [`Assertion`] that will always fail.
///
/// ```no_run
/// #[test]
/// fn fail() -> impl Assertion {
///     fail!().should_fail()
/// }
/// ```
#[macro_export]
macro_rules! fail {
    () => {
        $crate::assertion::Fail::manual_constructor(
            ::core::file!(),
            ::core::line!(),
            ::core::column!(),
        )
    };
}