assertables/
assert_eq.rs

1//! Assert an expression is equal to another.
2//!
3//! Pseudocode:<br>
4//! a = b
5//!
6//! # Module macro
7//!
8//! * [`assert_eq_as_result`](macro@crate::assert_eq_as_result)
9//!
10//! # Rust standard macros
11//!
12//! * [`assert_eq`](https://doc.rust-lang.org/std/macro.assert_eq.html)
13//! * [`debug_assert_eq`](https://doc.rust-lang.org/std/macro.debug_assert_eq.html)
14
15/// Assert an expression is equal to another.
16///
17/// Pseudocode:<br>
18/// a = b
19///
20/// * If true, return Result `Ok(())`.
21///
22/// * Otherwise, return Result `Err(message)`.
23///
24/// This macro is useful for runtime checks, such as checking parameters,
25/// or sanitizing inputs, or handling different results in different ways.
26///
27/// # Module macros
28///
29/// * [`assert_eq_as_result`](macro@crate::assert_eq_as_result)
30///
31/// # Rust standard macros
32///
33/// * [`assert_eq`](https://doc.rust-lang.org/std/macro.assert_eq.html)
34/// * [`debug_assert_eq`](https://doc.rust-lang.org/std/macro.debug_assert_eq.html)
35///
36#[macro_export]
37macro_rules! assert_eq_as_result {
38    ($a:expr, $b:expr $(,)?) => {
39        match (&$a, &$b) {
40            (a, b) => {
41                if a == b {
42                    Ok(())
43                } else {
44                    Err(format!(
45                        concat!(
46                            "assertion failed: `assert_eq!(a, b)`\n",
47                            "https://docs.rs/assertables/9.8.2/assertables/macro.assert_eq.html\n",
48                            " a label: `{}`,\n",
49                            " a debug: `{:?}`,\n",
50                            " b label: `{}`,\n",
51                            " b debug: `{:?}`",
52                        ),
53                        stringify!($a),
54                        a,
55                        stringify!($b),
56                        b
57                    ))
58                }
59            }
60        }
61    };
62}
63
64#[cfg(test)]
65mod test_assert_eq_as_result {
66    use std::sync::Once;
67
68    mod integer {
69        use super::*;
70
71        #[test]
72        fn eq() {
73            let a: i8 = 1;
74            let b: i8 = 1;
75            for _ in 0..1 {
76                let actual = assert_eq_as_result!(a, b);
77                assert_eq!(actual.unwrap(), ());
78            }
79        }
80
81        #[test]
82        fn eq_once() {
83            static A: Once = Once::new();
84            fn a() -> i8 {
85                if A.is_completed() {
86                    panic!("A.is_completed()")
87                } else {
88                    A.call_once(|| {})
89                }
90                1
91            }
92
93            static B: Once = Once::new();
94            fn b() -> i8 {
95                if B.is_completed() {
96                    panic!("B.is_completed()")
97                } else {
98                    B.call_once(|| {})
99                }
100                1
101            }
102
103            assert_eq!(A.is_completed(), false);
104            assert_eq!(B.is_completed(), false);
105            let result = assert_eq_as_result!(a(), b());
106            assert!(result.is_ok());
107            assert_eq!(A.is_completed(), true);
108            assert_eq!(B.is_completed(), true);
109        }
110
111        #[test]
112        fn lt() {
113            let a: i8 = 1;
114            let b: i8 = 2;
115            let actual = assert_eq_as_result!(a, b);
116            let message = concat!(
117                "assertion failed: `assert_eq!(a, b)`\n",
118                "https://docs.rs/assertables/9.8.2/assertables/macro.assert_eq.html\n",
119                " a label: `a`,\n",
120                " a debug: `1`,\n",
121                " b label: `b`,\n",
122                " b debug: `2`",
123            );
124            assert_eq!(actual.unwrap_err(), message);
125        }
126
127        #[test]
128        fn gt() {
129            let a: i8 = 2;
130            let b: i8 = 1;
131            let actual = assert_eq_as_result!(a, b);
132            let message = concat!(
133                "assertion failed: `assert_eq!(a, b)`\n",
134                "https://docs.rs/assertables/9.8.2/assertables/macro.assert_eq.html\n",
135                " a label: `a`,\n",
136                " a debug: `2`,\n",
137                " b label: `b`,\n",
138                " b debug: `1`",
139            );
140            assert_eq!(actual.unwrap_err(), message);
141        }
142    }
143
144    mod string {
145        use super::*;
146
147        #[test]
148        fn eq() {
149            let a: String = String::from("1");
150            let b: String = String::from("1");
151            for _ in 0..1 {
152                let actual = assert_eq_as_result!(a, b);
153                assert_eq!(actual.unwrap(), ());
154            }
155        }
156
157        #[test]
158        fn eq_once() {
159            static A: Once = Once::new();
160            fn a() -> String {
161                if A.is_completed() {
162                    panic!("A.is_completed()")
163                } else {
164                    A.call_once(|| {})
165                }
166                String::from("1")
167            }
168
169            static B: Once = Once::new();
170            fn b() -> String {
171                if B.is_completed() {
172                    panic!("B.is_completed()")
173                } else {
174                    B.call_once(|| {})
175                }
176                String::from("1")
177            }
178
179            assert_eq!(A.is_completed(), false);
180            assert_eq!(B.is_completed(), false);
181            let result = assert_eq_as_result!(a(), b());
182            assert!(result.is_ok());
183            assert_eq!(A.is_completed(), true);
184            assert_eq!(B.is_completed(), true);
185        }
186
187        #[test]
188        fn lt() {
189            let a: String = String::from("1");
190            let b: String = String::from("2");
191            let actual = assert_eq_as_result!(a, b);
192            let message = concat!(
193                "assertion failed: `assert_eq!(a, b)`\n",
194                "https://docs.rs/assertables/9.8.2/assertables/macro.assert_eq.html\n",
195                " a label: `a`,\n",
196                " a debug: `\"1\"`,\n",
197                " b label: `b`,\n",
198                " b debug: `\"2\"`",
199            );
200            assert_eq!(actual.unwrap_err(), message);
201        }
202
203        #[test]
204        fn gt() {
205            let a: String = String::from("2");
206            let b: String = String::from("1");
207            let actual = assert_eq_as_result!(a, b);
208            let message = concat!(
209                "assertion failed: `assert_eq!(a, b)`\n",
210                "https://docs.rs/assertables/9.8.2/assertables/macro.assert_eq.html\n",
211                " a label: `a`,\n",
212                " a debug: `\"2\"`,\n",
213                " b label: `b`,\n",
214                " b debug: `\"1\"`",
215            );
216            assert_eq!(actual.unwrap_err(), message);
217        }
218    }
219}