claims/
assert_none.rs

1/// Asserts that the expression is [`None`].
2///
3/// ## Uses
4///
5/// Assertions are always checked in both debug and release builds, and cannot be disabled.
6/// See [`debug_assert_none!`] for assertions that are not enabled in release builds by default.
7///
8/// ## Custom messages
9///
10/// This macro has a second form, where a custom panic message can be provided with or without
11/// arguments for formatting. See [`std::fmt`] for syntax for this form.
12///
13/// ## Examples
14///
15/// ```rust
16/// # #[macro_use] extern crate claims;
17/// # fn main() {
18/// let maybe: Option<i32> = None;
19///
20/// assert_none!(maybe);
21///
22/// // With a custom message
23/// assert_none!(maybe, "Yep, there is nothing in here");
24/// assert_none!(maybe, "we asserting that there are no droids we are looking for at {:?}", maybe);
25/// # }
26/// ```
27///
28/// A `Some(_)` variant will panic:
29///
30/// ```rust,should_panic
31/// # #[macro_use] extern crate claims;
32/// # fn main() {
33/// let maybe = Some(42i32);
34///
35/// assert_none!(maybe);  // Will panic
36/// # }
37/// ```
38///
39/// [`None`]: https://doc.rust-lang.org/core/option/enum.Option.html#variant.None
40/// [`std::fmt`]: https://doc.rust-lang.org/std/fmt/index.html
41/// [`debug_assert_none!`]: crate::debug_assert_none!
42#[macro_export]
43macro_rules! assert_none {
44    ($cond:expr $(,)?) => {
45        match $cond {
46            none @ ::core::option::Option::None => none,
47            some @ ::core::option::Option::Some(_) => {
48                ::core::panic!("assertion failed, expected None, got {:?}", some);
49            }
50        }
51    };
52    ($cond:expr, $($arg:tt)+) => {
53        match $cond {
54            none @ ::core::option::Option::None => none,
55            some @ ::core::option::Option::Some(_) => {
56                ::core::panic!("assertion failed, expected None, got {:?}: {}", some, ::core::format_args!($($arg)+));
57            }
58        }
59    };
60}
61
62/// Asserts that the expression is [`None`] on debug builds.
63///
64/// This macro behaves the same as [`assert_none!`] on debug builds. On release builds it is a
65/// no-op.
66#[macro_export]
67macro_rules! debug_assert_none {
68    ($($arg:tt)*) => {
69        #[cfg(debug_assertions)]
70        $crate::assert_none!($($arg)*);
71    }
72}
73
74#[cfg(test)]
75mod tests {
76    #[test]
77    fn none() {
78        assert_none!(None::<()>);
79    }
80
81    #[test]
82    #[should_panic(expected = "assertion failed, expected None, got Some(())")]
83    fn not_none() {
84        assert_none!(Some(()));
85    }
86
87    #[test]
88    #[should_panic(expected = "assertion failed, expected None, got Some(()): foo")]
89    fn not_none_custom_message() {
90        assert_none!(Some(()), "foo");
91    }
92
93    #[test]
94    #[cfg_attr(not(debug_assertions), ignore = "only run in debug mode")]
95    fn debug_none() {
96        debug_assert_none!(None::<()>);
97    }
98
99    #[test]
100    #[cfg_attr(not(debug_assertions), ignore = "only run in debug mode")]
101    #[should_panic(expected = "assertion failed, expected None, got Some(())")]
102    fn debug_not_none() {
103        debug_assert_none!(Some(()));
104    }
105
106    #[test]
107    #[cfg_attr(not(debug_assertions), ignore = "only run in debug mode")]
108    #[should_panic(expected = "assertion failed, expected None, got Some(()): foo")]
109    fn debug_not_none_custom_message() {
110        debug_assert_none!(Some(()), "foo");
111    }
112
113    #[test]
114    #[cfg_attr(debug_assertions, ignore = "only run in release mode")]
115    fn debug_release_not_none() {
116        debug_assert_none!(Some(()));
117    }
118}