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 about two objects `lhs` and `rhs`.
#[must_use = "assertions do not fire unless returned from a test"]
pub struct BinaryAssertion<T, U> {
    lhs: T,
    rhs: U,
    test_result: bool,
    test_repr: &'static str,
    info: AssertInfo,
}

impl<T, U> Display for BinaryAssertion<T, U>
where
    T: Debug,
    U: Debug,
{
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        let Self {
            lhs,
            rhs,
            test_result: _,
            test_repr,
            info: AssertInfo { file, line, column },
        } = self;

        write!(
            f,
            "assertion starting at {file}:{line}:{column} failed: `{test_repr}`\n lhs: {lhs:?}\n rhs: {rhs:?}"
        )
    }
}

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

impl<T, U> BinaryAssertion<T, U> {
    pub(crate) const fn new(
        lhs: T,
        rhs: U,
        test_result: bool,
        test_repr: &'static str,
        info: AssertInfo,
    ) -> Self {
        Self {
            lhs,
            rhs,
            test_result,
            test_repr,
            info,
        }
    }
}

#[cfg(feature = "std")]
impl<T, U> std::process::Termination for BinaryAssertion<T, U>
where
    T: Debug,
    U: Debug,
{
    fn report(self) -> std::process::ExitCode {
        if self.test() {
            std::process::ExitCode::SUCCESS
        } else {
            println!("{self}");
            std::process::ExitCode::FAILURE
        }
    }
}

impl<T, U> Assertion for BinaryAssertion<T, U>
where
    T: Debug,
    U: Debug,
{
    fn test(&self) -> bool {
        self.test_result
    }
}