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 non_negative_impl<T: Default + Display + PartialOrd>(
56    a: &T,
57) -> Result<(), AssertionError> {
58    if a >= &T::default() {
59        Ok(())
60    } else {
61        Err(AssertionError {
62            message: format!(
63                "\n\x1b[1;91mAssertion `left >= right` failed.\n\x1b[0;91m  left: {a}\n right: 0\x1b[0m"
64            ),
65        })
66    }
67}
68
69pub(super) fn zero_within_tols_impl<T: Display + Tensor>(
70    tols: &Assert,
71    a: &T,
72) -> Result<(), AssertionError> {
73    if let Some(count) = a.error_count_zero(tols.abs_tol, tols.rel_tol) {
74        Err(AssertionError {
75            message: format!(
76                "\n\x1b[1;91mAssertion `left ≈= right` failed in {count} places.\n\x1b[0;91m  left: {a}\n right: 0\x1b[0m"
77            ),
78        })
79    } else {
80        Ok(())
81    }
82}
83
84impl<T> AssertEq<T> for &T
85where
86    T: Display + PartialEq + Tensor,
87{
88    fn eq(a: Self, b: T) -> Result<(), AssertionError> {
89        eq_impl(a, &b)
90    }
91    fn eq_within_tols(tols: &Assert, a: Self, b: T) -> Result<(), AssertionError> {
92        eq_within_tols_impl(tols, a, &b)
93    }
94}
95
96impl<'a, T> AssertEq<&'a T> for T
97where
98    T: Display + PartialEq + Tensor,
99{
100    fn eq(a: Self, b: &'a T) -> Result<(), AssertionError> {
101        eq_impl(&a, b)
102    }
103    fn eq_within_tols(tols: &Assert, a: Self, b: &'a T) -> Result<(), AssertionError> {
104        eq_within_tols_impl(tols, &a, b)
105    }
106}
107
108impl<'a, T> AssertEq<&'a T> for &'a T
109where
110    T: Display + PartialEq + Tensor,
111{
112    fn eq(a: Self, b: &'a T) -> Result<(), AssertionError> {
113        eq_impl(a, b)
114    }
115    fn eq_within_tols(tols: &Assert, a: Self, b: &'a T) -> Result<(), AssertionError> {
116        eq_within_tols_impl(tols, a, b)
117    }
118}