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