Skip to main content

assert_rs/assertion/
multi_dyn.rs

1use super::{Assertion, Debug, Display};
2
3extern crate alloc;
4use alloc::boxed::Box;
5
6/// A group of assertions, possibly of different types, all tested simultaneously.
7///
8/// These can be created using the [`multi_assert!`](crate::multi_assert) macro.
9/// See its docs for more.
10pub struct MultiDynAssertion<const N: usize>([Box<dyn Assertion>; N]);
11
12impl<const N: usize> Display for MultiDynAssertion<N> {
13    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
14        write!(f, "assertion failures in a multi-assert:")?;
15        for (i, assertion) in self.0.iter().enumerate() {
16            if assertion.test() {
17                write!(f, "\n{i}. [ok]")?;
18            } else {
19                writeln!(f, "\n{i}. {assertion}")?;
20            }
21        }
22        Ok(())
23    }
24}
25
26impl<const N: usize> MultiDynAssertion<N> {
27    #[must_use]
28    #[doc(hidden)]
29    /// You can use [`multi_assert!`](crate::multi_assert) with `#[dyn]` instead, but it's not required.
30    pub fn new(assertions: [Box<dyn Assertion>; N]) -> Self {
31        Self(assertions)
32    }
33}
34
35#[cfg(feature = "std")]
36impl<const N: usize> std::process::Termination for MultiDynAssertion<N> {
37    fn report(self) -> std::process::ExitCode {
38        if self.test() {
39            std::process::ExitCode::SUCCESS
40        } else {
41            println!("{self}");
42            std::process::ExitCode::FAILURE
43        }
44    }
45}
46
47impl<const N: usize> Assertion for MultiDynAssertion<N> {
48    fn test(&self) -> bool {
49        self.0.iter().all(|a| a.test())
50    }
51}
52
53impl<const N: usize> Debug for MultiDynAssertion<N> {
54    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
55        Display::fmt(self, f)
56    }
57}