claims/
assert_ready_eq.rs

1/// Asserts that the left expression contains a [`Poll::Ready(T)`] variant and its contained value of type
2/// `T` equals the right expression.
3///
4/// ## Uses
5///
6/// Assertions are always checked in both debug and release builds, and cannot be disabled.
7/// See [`debug_assert_ready_eq!`] for assertions that are not enabled in release builds by default.
8///
9/// ## Custom messages
10///
11/// This macro has a second form, where a custom panic message can be provided with or without
12/// arguments for formatting. See [`std::fmt`] for syntax for this form.
13///
14/// ## Examples
15///
16/// ```rust
17/// # #[macro_use] extern crate claims;
18/// # use std::task::Poll;
19/// # fn main() {
20/// let res: Poll<Result<i32, ()>> = Poll::Ready(Ok(42));
21///
22/// assert_ready_eq!(res, Ok(42));
23/// # }
24/// ```
25///
26/// The contained value will also be returned from this macro call:
27///
28/// ```rust
29/// # #[macro_use] extern crate claims;
30/// # use std::task::Poll;
31/// # fn main() {
32/// let res: Poll<Result<i32, ()>> = Poll::Ready(Ok(42));
33///
34/// let value = assert_ready_eq!(res, Ok(42));
35/// assert_eq!(value, Ok(42));
36/// # }
37/// ```
38///
39/// A [`Poll::Pending`] variant will panic:
40///
41/// ```rust,should_panic
42/// # #[macro_use] extern crate claims;
43/// # use std::task::Poll;
44/// # fn main() {
45/// let res: Poll<Result<i32, ()>> = Poll::Pending;
46///
47/// assert_ready_eq!(res, Ok(42));  // Will panic
48/// # }
49/// ```
50///
51/// [`Poll::Ready(Ok(T))`]: https://doc.rust-lang.org/core/task/enum.Poll.html#variant.Ready
52/// [`Poll::Pending`]: https://doc.rust-lang.org/core/task/enum.Poll.html#variant.Pending
53/// [`std::fmt`]: https://doc.rust-lang.org/std/fmt/index.html
54/// [`debug_assert_ready_eq!`]: crate::debug_assert_ready_eq!
55#[macro_export]
56macro_rules! assert_ready_eq {
57    ($cond:expr, $expected:expr $(,)?) => {
58        match $cond {
59            ::core::task::Poll::Ready(t) => {
60                ::core::assert_eq!(t, $expected);
61                t
62            },
63            ::core::task::Poll::Pending => {
64                ::core::panic!("assertion failed, expected Ready(_), got Pending");
65            }
66        }
67    };
68    ($cond:expr, $expected:expr, $($arg:tt)+) => {
69        match $cond {
70            ::core::task::Poll::Ready(t) => {
71                ::core::assert_eq!(t, $expected, $($arg)+);
72                t
73            },
74            ::core::task::Poll::Pending => {
75                ::core::panic!("assertion failed, expected Ready(_), got Pending: {}", ::core::format_args!($($arg)+));
76            }
77        }
78    };
79}
80
81/// Asserts that the left expression contains a [`Poll::Ready(T)`] variant and its contained value of type
82/// `T` equals the right expression on debug builds.
83///
84/// This macro behaves nearly the same as [`assert_ready_eq!`] on debug builds, although it does not
85/// return the value contained in the `Poll::Ready` variant. On release builds it is a no-op.
86///
87/// [`Poll::Ready(T)`]: https://doc.rust-lang.org/core/task/enum.Poll.html#variant.Ready
88#[macro_export]
89macro_rules! debug_assert_ready_eq {
90    ($($arg:tt)*) => {
91        #[cfg(debug_assertions)]
92        $crate::assert_ready_eq!($($arg)*);
93    }
94}
95
96#[cfg(test)]
97mod tests {
98    use core::task::Poll::{Pending, Ready};
99
100    #[test]
101    fn equal() {
102        assert_ready_eq!(Ready(42), 42);
103    }
104
105    #[test]
106    #[should_panic]
107    fn not_equal() {
108        assert_ready_eq!(Ready(42), 100);
109    }
110
111    #[test]
112    #[should_panic(expected = "assertion failed, expected Ready(_), got Pending")]
113    fn not_ready() {
114        assert_ready_eq!(Pending::<usize>, 42);
115    }
116
117    #[test]
118    #[should_panic(expected = "foo")]
119    fn not_equal_custom_message() {
120        assert_ready_eq!(Ready(1), 2, "foo");
121    }
122
123    #[test]
124    #[should_panic(expected = "assertion failed, expected Ready(_), got Pending: foo")]
125    fn not_ready_custom_message() {
126        assert_ready_eq!(Pending::<usize>, 2, "foo");
127    }
128
129    #[test]
130    #[cfg_attr(not(debug_assertions), ignore = "only run in debug mode")]
131    fn debug_equal() {
132        debug_assert_ready_eq!(Ready(42), 42);
133    }
134
135    #[test]
136    #[cfg_attr(not(debug_assertions), ignore = "only run in debug mode")]
137    #[should_panic]
138    fn debug_not_equal() {
139        debug_assert_ready_eq!(Ready(42), 100);
140    }
141
142    #[test]
143    #[cfg_attr(not(debug_assertions), ignore = "only run in debug mode")]
144    #[should_panic(expected = "assertion failed, expected Ready(_), got Pending")]
145    fn debug_not_ready() {
146        debug_assert_ready_eq!(Pending::<usize>, 42);
147    }
148
149    #[test]
150    #[cfg_attr(not(debug_assertions), ignore = "only run in debug mode")]
151    #[should_panic(expected = "foo")]
152    fn debug_not_equal_custom_message() {
153        debug_assert_ready_eq!(Ready(1), 2, "foo");
154    }
155
156    #[test]
157    #[cfg_attr(not(debug_assertions), ignore = "only run in debug mode")]
158    #[should_panic(expected = "assertion failed, expected Ready(_), got Pending: foo")]
159    fn debug_not_ready_custom_message() {
160        debug_assert_ready_eq!(Pending::<usize>, 2, "foo");
161    }
162
163    #[test]
164    #[cfg_attr(debug_assertions, ignore = "only run in release mode")]
165    fn debug_release_not_equal() {
166        debug_assert_ready_eq!(Ready(42), 100);
167    }
168
169    #[test]
170    #[cfg_attr(debug_assertions, ignore = "only run in release mode")]
171    fn debug_release_not_ready() {
172        debug_assert_ready_eq!(Pending::<usize>, 42);
173    }
174}