assert-rs 0.1.1

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

extern crate alloc;
use alloc::boxed::Box;

/// A group of assertions, possibly of different types, all tested simultaneously.
///
/// These can be created using the [`multi_assert!`](crate::multi_assert) macro.
/// See its docs for more.
pub struct MultiDynAssertion<const N: usize>([Box<dyn Assertion>; N]);

impl<const N: usize> Display for MultiDynAssertion<N> {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        write!(f, "assertion failures in a multi-assert:")?;
        for (i, assertion) in self.0.iter().enumerate() {
            if assertion.test() {
                write!(f, "\n{i}. [ok]")?;
            } else {
                writeln!(f, "\n{i}. {assertion}")?;
            }
        }
        Ok(())
    }
}

impl<const N: usize> MultiDynAssertion<N> {
    #[must_use]
    #[doc(hidden)]
    /// You can use [`multi_assert!`](crate::multi_assert) with `#[dyn]` instead, but it's not required.
    pub fn new(assertions: [Box<dyn Assertion>; N]) -> Self {
        Self(assertions)
    }
}

#[cfg(feature = "std")]
impl<const N: usize> std::process::Termination for MultiDynAssertion<N> {
    fn report(self) -> std::process::ExitCode {
        if self.test() {
            std::process::ExitCode::SUCCESS
        } else {
            println!("{self}");
            std::process::ExitCode::FAILURE
        }
    }
}

impl<const N: usize> Assertion for MultiDynAssertion<N> {
    fn test(&self) -> bool {
        self.0.iter().all(|a| a.test())
    }
}

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