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}