Skip to main content

assert_rs/assertion/
multi.rs

1use super::{Assertion, Debug, Display};
2
3/// A group of assertions, all tested simultaneously.
4///
5/// These can be created using the [`multi_assert!`](crate::multi_assert) macro.
6/// See its docs for more.
7pub struct MultiAssertion<A: Assertion, const N: usize>([A; N]);
8
9impl<A: Assertion, const N: usize> Display for MultiAssertion<A, N> {
10    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
11        write!(f, "assertion failures in a multi-assert:")?;
12        for (i, assertion) in self.0.iter().enumerate() {
13            if assertion.test() {
14                write!(f, "\n{i}. [ok]")?;
15            } else {
16                writeln!(f, "\n{i}. {assertion}")?;
17            }
18        }
19        Ok(())
20    }
21}
22
23impl<A: Assertion, const N: usize> MultiAssertion<A, N> {
24    #[must_use]
25    /// You can use [`multi_assert!`](crate::multi_assert) instead, but it's not required.
26    pub const fn new(assertions: [A; N]) -> Self {
27        Self(assertions)
28    }
29}
30
31#[cfg(feature = "std")]
32impl<A: Assertion, const N: usize> std::process::Termination for MultiAssertion<A, N> {
33    fn report(self) -> std::process::ExitCode {
34        if self.test() {
35            std::process::ExitCode::SUCCESS
36        } else {
37            println!("{self}");
38            std::process::ExitCode::FAILURE
39        }
40    }
41}
42
43impl<A: Assertion, const N: usize> Assertion for MultiAssertion<A, N> {
44    fn test(&self) -> bool {
45        self.0.iter().all(Assertion::test)
46    }
47}
48
49impl<A: Assertion, const N: usize> Debug for MultiAssertion<A, N> {
50    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
51        Display::fmt(self, f)
52    }
53}
54
55#[cfg(feature = "alloc")]
56#[cfg_attr(doc, doc = include_str!("../multi_assert_doc.md"))]
57#[macro_export]
58macro_rules! multi_assert {
59    [#[dyn] $($this:expr),+ $(,)?] => {
60        $crate::assertion::MultiDynAssertion::new([
61            $(Box::new($this),)+
62        ])
63    };
64    [$($this:expr),+ $(,)?] => {
65        $crate::assertion::MultiAssertion::new([
66            $($this,)+
67        ])
68    };
69}
70
71#[cfg(not(feature = "alloc"))]
72#[cfg_attr(doc, doc = include_str!("../multi_assert_doc.md"))]
73#[macro_export]
74macro_rules! multi_assert {
75    [#[dyn] $($this:expr),+ $(,)?] => {
76        compile_error!("cannot use #[dyn] if the no_alloc feature is enabled")
77    };
78    [$($this:expr),+ $(,)?] => {
79        $crate::assertion::MultiAssertion::new([
80            $($this,)+
81        ])
82    };
83}