Skip to main content

conspire/math/assert/eq/
mod.rs

1mod owned;
2
3use super::{Assert, AssertionError};
4use crate::math::Tensor;
5use std::fmt::Display;
6
7/// Equality assertions, overloaded across owned and borrowed operands.
8pub trait AssertEq<Rhs = Self> {
9    fn eq(a: Self, b: Rhs) -> Result<(), AssertionError>;
10    fn eq_within_tols(tols: &Assert, a: Self, b: Rhs) -> Result<(), AssertionError>;
11}
12
13pub(super) fn eq_impl<T: Display + PartialEq>(a: &T, b: &T) -> Result<(), AssertionError> {
14    if a == b {
15        Ok(())
16    } else {
17        Err(AssertionError {
18            message: format!(
19                "\n\x1b[1;91mAssertion `left == right` failed.\n\x1b[0;91m  left: {a}\n right: {b}\x1b[0m"
20            ),
21        })
22    }
23}
24
25pub(super) fn eq_within_tols_impl<T: Display + Tensor>(
26    tols: &Assert,
27    a: &T,
28    b: &T,
29) -> Result<(), AssertionError> {
30    if let Some(count) = a.error_count(b, tols.abs_tol, tols.rel_tol) {
31        let abs = a.sub_abs(b);
32        let rel = a.sub_rel(b);
33        Err(AssertionError {
34            message: format!(
35                "\n\x1b[1;91mAssertion `left ≈= right` failed in {count} places.\n\x1b[0;91m  left: {a}\n right: {b}\n   abs: {abs}\n   rel: {rel}\x1b[0m"
36            ),
37        })
38    } else {
39        Ok(())
40    }
41}
42
43pub(super) fn zero_impl<T: Display + Tensor>(a: &T) -> Result<(), AssertionError> {
44    if a.is_zero() {
45        Ok(())
46    } else {
47        Err(AssertionError {
48            message: format!(
49                "\n\x1b[1;91mAssertion `left == right` failed.\n\x1b[0;91m  left: {a}\n right: 0\x1b[0m"
50            ),
51        })
52    }
53}
54
55pub(super) fn zero_within_tols_impl<T: Display + Tensor>(
56    tols: &Assert,
57    a: &T,
58) -> Result<(), AssertionError> {
59    if let Some(count) = a.error_count_zero(tols.abs_tol, tols.rel_tol) {
60        Err(AssertionError {
61            message: format!(
62                "\n\x1b[1;91mAssertion `left ≈= right` failed in {count} places.\n\x1b[0;91m  left: {a}\n right: 0\x1b[0m"
63            ),
64        })
65    } else {
66        Ok(())
67    }
68}
69
70impl<T> AssertEq<T> for &T
71where
72    T: Display + PartialEq + Tensor,
73{
74    fn eq(a: Self, b: T) -> Result<(), AssertionError> {
75        eq_impl(a, &b)
76    }
77    fn eq_within_tols(tols: &Assert, a: Self, b: T) -> Result<(), AssertionError> {
78        eq_within_tols_impl(tols, a, &b)
79    }
80}
81
82impl<'a, T> AssertEq<&'a T> for T
83where
84    T: Display + PartialEq + Tensor,
85{
86    fn eq(a: Self, b: &'a T) -> Result<(), AssertionError> {
87        eq_impl(&a, b)
88    }
89    fn eq_within_tols(tols: &Assert, a: Self, b: &'a T) -> Result<(), AssertionError> {
90        eq_within_tols_impl(tols, &a, b)
91    }
92}
93
94impl<'a, T> AssertEq<&'a T> for &'a T
95where
96    T: Display + PartialEq + Tensor,
97{
98    fn eq(a: Self, b: &'a T) -> Result<(), AssertionError> {
99        eq_impl(a, b)
100    }
101    fn eq_within_tols(tols: &Assert, a: Self, b: &'a T) -> Result<(), AssertionError> {
102        eq_within_tols_impl(tols, a, b)
103    }
104}