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