Skip to main content

assertables/assert_ready/
assert_ready_eq.rs

1//! Assert two expressions are Ready and their values are equal.
2//!
3//! Pseudocode:<br>
4//! (a ⇒ Ready(a1) ⇒ a1) = (b ⇒ Ready(b1) ⇒ b1)
5//!
6//! # Example
7//!
8//! ```rust
9//! use assertables::*;
10//! use std::task::Poll;
11//! use std::task::Poll::*;
12//! let a: Poll<i8> = Ready(1);
13//! let b: Poll<i8> = Ready(1);
14//! assert_ready_eq!(a, b);
15//! ```
16//!
17//! # Module macros
18//!
19//! * [`assert_ready_eq`](macro@crate::assert_ready_eq)
20//! * [`assert_ready_eq_as_result`](macro@crate::assert_ready_eq_as_result)
21//! * [`debug_assert_ready_eq`](macro@crate::debug_assert_ready_eq)
22
23/// Assert two expressions are Ready and their values are equal.
24///
25/// Pseudocode:<br>
26/// (a ⇒ Ready(a1) ⇒ a1) = (b ⇒ Ready(b1) ⇒ b1)
27///
28/// * If true, return Result `Ok((a1, b1))`.
29///
30/// * Otherwise, return Result `Err(message)`.
31///
32/// This macro provides the same statements as [`assert_ready_eq`](macro.assert_ready_eq.html),
33/// except this macro returns a Option, rather than doing a panic.
34///
35/// This macro is useful for runtime checks, such as checking parameters,
36/// or sanitizing inputs, or handling different results in different ways.
37///
38/// # Module macros
39///
40/// * [`assert_ready_eq`](macro@crate::assert_ready_eq)
41/// * [`assert_ready_eq_as_result`](macro@crate::assert_ready_eq_as_result)
42/// * [`debug_assert_ready_eq`](macro@crate::debug_assert_ready_eq)
43///
44#[macro_export]
45macro_rules! assert_ready_eq_as_result {
46    ($a:expr, $b:expr $(,)?) => {
47        match ($a, $b) {
48            (Ready(a1), Ready(b1)) => {
49                if a1 == b1 {
50                    Ok((a1, b1))
51                } else {
52                    Err(format!(
53                        concat!(
54                            "assertion failed: `assert_ready_eq!(a, b)`\n",
55                            "https://docs.rs/assertables/9.8.5/assertables/macro.assert_ready_eq.html\n",
56                            " a label: `{}`,\n",
57                            " a debug: `{:?}`,\n",
58                            " a inner: `{:?}`,\n",
59                            " b label: `{}`,\n",
60                            " b debug: `{:?}`,\n",
61                            " b inner: `{:?}`"
62                        ),
63                        stringify!($a),
64                        $a,
65                        a1,
66                        stringify!($b),
67                        $b,
68                        b1
69                    ))
70                }
71            }
72            _ => Err(format!(
73                concat!(
74                    "assertion failed: `assert_ready_eq!(a, b)`\n",
75                    "https://docs.rs/assertables/9.8.5/assertables/macro.assert_ready_eq.html\n",
76                    " a label: `{}`,\n",
77                    " a debug: `{:?}`,\n",
78                    " b label: `{}`,\n",
79                    " b debug: `{:?}`",
80                ),
81                stringify!($a),
82                $a,
83                stringify!($b),
84                $b
85            )),
86        }
87    };
88}
89
90#[cfg(test)]
91mod test_assert_ready_eq_as_result {
92    // use std::sync::Once;
93    use std::task::Poll;
94    use std::task::Poll::*;
95
96    #[test]
97    fn eq() {
98        let a: Poll<i8> = Ready(1);
99        let b: Poll<i8> = Ready(1);
100        for _ in 0..1 {
101            let actual = assert_ready_eq_as_result!(a, b);
102            assert_eq!(actual.unwrap(), (1, 1));
103        }
104    }
105
106    #[test]
107    fn ne() {
108        let a: Poll<i8> = Ready(1);
109        let b: Poll<i8> = Ready(2);
110        let actual = assert_ready_eq_as_result!(a, b);
111        let message = concat!(
112            "assertion failed: `assert_ready_eq!(a, b)`\n",
113            "https://docs.rs/assertables/9.8.5/assertables/macro.assert_ready_eq.html\n",
114            " a label: `a`,\n",
115            " a debug: `Ready(1)`,\n",
116            " a inner: `1`,\n",
117            " b label: `b`,\n",
118            " b debug: `Ready(2)`,\n",
119            " b inner: `2`",
120        );
121        assert_eq!(actual.unwrap_err(), message);
122    }
123
124    #[test]
125    fn failure_because_not_ready() {
126        let a: Poll<i8> = Pending;
127        let b: Poll<i8> = Ready(1);
128        let actual = assert_ready_eq_as_result!(a, b);
129        let message = concat!(
130            "assertion failed: `assert_ready_eq!(a, b)`\n",
131            "https://docs.rs/assertables/9.8.5/assertables/macro.assert_ready_eq.html\n",
132            " a label: `a`,\n",
133            " a debug: `Pending`,\n",
134            " b label: `b`,\n",
135            " b debug: `Ready(1)`",
136        );
137        assert_eq!(actual.unwrap_err(), message);
138    }
139}
140
141/// Assert two expressions are Ready and their values are equal.
142///
143/// Pseudocode:<br>
144/// (a ⇒ Ready(a1) ⇒ a1) = (b ⇒ Ready(b1) ⇒ b1)
145///
146/// * If true, return `(a1, b1)`.
147///
148/// * Otherwise, call [`panic!`] with a message and the values of the
149///   expressions with their debug representations.
150///
151/// # Examples
152///
153/// ```rust
154/// use assertables::*;
155/// # use std::panic;
156/// use std::task::Poll;
157/// use std::task::Poll::*;
158/// # fn main() {
159/// let a: Poll<i8> = Ready(1);
160/// let b: Poll<i8> = Ready(1);
161/// assert_ready_eq!(a, b);
162///
163/// # let result = panic::catch_unwind(|| {
164/// // This will panic
165/// let a: Poll<i8> = Ready(1);
166/// let b: Poll<i8> = Ready(2);
167/// assert_ready_eq!(a, b);
168/// # });
169/// // assertion failed: `assert_ready_eq!(a, b)`
170/// // https://docs.rs/assertables/…/assertables/macro.assert_ready_eq.html
171/// //  a label: `a`,
172/// //  a debug: `Ready(1)`,
173/// //  a inner: `1`,
174/// //  b label: `b`,
175/// //  b debug: `Ready(2)`,
176/// //  b inner: `2`
177/// # let actual = result.unwrap_err().downcast::<String>().unwrap().to_string();
178/// # let message = concat!(
179/// #     "assertion failed: `assert_ready_eq!(a, b)`\n",
180/// #     "https://docs.rs/assertables/9.8.5/assertables/macro.assert_ready_eq.html\n",
181/// #     " a label: `a`,\n",
182/// #     " a debug: `Ready(1)`,\n",
183/// #     " a inner: `1`,\n",
184/// #     " b label: `b`,\n",
185/// #     " b debug: `Ready(2)`,\n",
186/// #     " b inner: `2`",
187/// # );
188/// # assert_eq!(actual, message);
189/// # }
190/// ```
191///
192/// # Module macros
193///
194/// * [`assert_ready_eq`](macro@crate::assert_ready_eq)
195/// * [`assert_ready_eq_as_result`](macro@crate::assert_ready_eq_as_result)
196/// * [`debug_assert_ready_eq`](macro@crate::debug_assert_ready_eq)
197///
198#[macro_export]
199macro_rules! assert_ready_eq {
200    ($a:expr, $b:expr $(,)?) => {
201        match $crate::assert_ready_eq_as_result!($a, $b) {
202            Ok(x) => x,
203            Err(err) => panic!("{}", err),
204        }
205    };
206    ($a:expr, $b:expr, $($message:tt)+) => {
207        match $crate::assert_ready_eq_as_result!($a, $b) {
208            Ok(x) => x,
209            Err(err) => panic!("{}\n{}", format_args!($($message)+), err),
210        }
211    };
212}
213
214#[cfg(test)]
215mod test_assert_ready_eq {
216    use std::panic;
217    use std::task::Poll;
218    use std::task::Poll::*;
219
220    #[test]
221    fn eq() {
222        let a: Poll<i8> = Ready(1);
223        let b: Poll<i8> = Ready(1);
224        for _ in 0..1 {
225            let actual = assert_ready_eq!(a, b);
226            assert_eq!(actual, (1, 1));
227        }
228    }
229
230    #[test]
231    fn ne() {
232        let a: Poll<i8> = Ready(1);
233        let b: Poll<i8> = Ready(2);
234        let result = panic::catch_unwind(|| {
235            let _actual = assert_ready_eq!(a, b);
236        });
237        let message = concat!(
238            "assertion failed: `assert_ready_eq!(a, b)`\n",
239            "https://docs.rs/assertables/9.8.5/assertables/macro.assert_ready_eq.html\n",
240            " a label: `a`,\n",
241            " a debug: `Ready(1)`,\n",
242            " a inner: `1`,\n",
243            " b label: `b`,\n",
244            " b debug: `Ready(2)`,\n",
245            " b inner: `2`",
246        );
247        assert_eq!(
248            result
249                .unwrap_err()
250                .downcast::<String>()
251                .unwrap()
252                .to_string(),
253            message
254        );
255    }
256
257    #[test]
258    fn not_ready() {
259        let a: Poll<i8> = Pending;
260        let b: Poll<i8> = Ready(1);
261        let result = panic::catch_unwind(|| {
262            let _actual = assert_ready_eq!(a, b);
263        });
264        let message = concat!(
265            "assertion failed: `assert_ready_eq!(a, b)`\n",
266            "https://docs.rs/assertables/9.8.5/assertables/macro.assert_ready_eq.html\n",
267            " a label: `a`,\n",
268            " a debug: `Pending`,\n",
269            " b label: `b`,\n",
270            " b debug: `Ready(1)`",
271        );
272        assert_eq!(
273            result
274                .unwrap_err()
275                .downcast::<String>()
276                .unwrap()
277                .to_string(),
278            message
279        );
280    }
281}
282
283/// Assert two expressions are Ready and their values are equal.
284///
285/// Pseudocode:<br>
286/// (a ⇒ Ready(a1) ⇒ a1) = (b ⇒ Ready(b1) ⇒ b1)
287///
288/// This macro provides the same statements as [`assert_ready_eq`](macro.assert_ready_eq.html),
289/// except this macro's statements are only enabled in non-optimized
290/// builds by default. An optimized build will not execute this macro's
291/// statements unless `-C debug-assertions` is passed to the compiler.
292///
293/// This macro is useful for checks that are too expensive to be present
294/// in a release build but may be helpful during development.
295///
296/// The result of expanding this macro is always type checked.
297///
298/// An unchecked assertion allows a program in an inconsistent state to
299/// keep running, which might have unexpected consequences but does not
300/// introduce unsafety as long as this only happens in safe code. The
301/// performance cost of assertions, however, is not measurable in general.
302/// Replacing `assert*!` with `debug_assert*!` is thus only encouraged
303/// after thorough profiling, and more importantly, only in safe code!
304///
305/// This macro is intended to work in a similar way to
306/// [`::std::debug_assert`](https://doc.rust-lang.org/std/macro.debug_assert.html).
307///
308/// # Module macros
309///
310/// * [`assert_ready_eq`](macro@crate::assert_ready_eq)
311/// * [`assert_ready_eq`](macro@crate::assert_ready_eq)
312/// * [`debug_assert_ready_eq`](macro@crate::debug_assert_ready_eq)
313///
314#[macro_export]
315macro_rules! debug_assert_ready_eq {
316    ($($arg:tt)*) => {
317        if cfg!(debug_assertions) {
318            $crate::assert_ready_eq!($($arg)*);
319        }
320    };
321}