assertables/assert_ready/
assert_ready_eq_x.rs

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