claims/
assert_ge.rs

1/// Asserts that the first expression is greater than or equal to the second.
2///
3/// Requires that both expressions be comparable with `>=`.
4///
5/// ## Uses
6///
7/// Assertions are always checked in both debug and release builds, and cannot be disabled.
8/// See [`debug_assert_ge!`] for assertions that are not enabled in release builds by default.
9///
10/// ## Custom messages
11///
12/// This macro has a second form, where a custom panic message can be provided with or without
13/// arguments for formatting. See [`std::fmt`] for syntax for this form.
14///
15/// ## Examples
16///
17/// ```rust
18/// # #[macro_use] extern crate claims;
19/// # fn main() {
20/// assert_ge!(2, 1);
21///
22/// // With a custom message.
23/// assert_ge!(2, 1, "Expecting that {} is greater or equal than {}", 2, 1);
24/// assert_ge!(5, 5, "Expecting that both arguments are equal");
25/// # }
26/// ```
27///
28/// ```rust,should_panic
29/// # #[macro_use] extern crate claims;
30/// # fn main() {
31/// assert_ge!(5, 6);  // Will panic
32/// # }
33/// ```
34///
35/// [`std::fmt`]: https://doc.rust-lang.org/std/fmt/index.html
36/// [`debug_assert_ge!`]: crate::debug_assert_ge!
37#[macro_export]
38macro_rules! assert_ge {
39    ($left:expr, $right:expr $(,)?) => {
40        match (&$left, &$right) {
41            (left_val, right_val) => {
42                if !(*left_val >= *right_val) {
43                    // The reborrows below are intentional. Without them, the stack slot for the
44                    // borrow is initialized even before the values are compared, leading to a
45                    // noticeable slow down.
46                    ::core::panic!(r#"assertion failed: `(left >= right)`
47    left: `{:?}`,
48    right: `{:?}`"#, &*left_val, &*right_val)
49                }
50            }
51        }
52    };
53    ($left:expr, $right:expr, $($arg:tt)+) => {
54        match (&$left, &$right) {
55            (left_val, right_val) => {
56                if !(*left_val >= *right_val) {
57                    // The reborrows below are intentional. Without them, the stack slot for the
58                    // borrow is initialized even before the values are compared, leading to a
59                    // noticeable slow down.
60                    ::core::panic!(r#"assertion failed: `(left >= right)`
61    left: `{:?}`,
62    right: `{:?}`: {}"#, &*left_val, &*right_val, ::core::format_args!($($arg)+))
63                }
64            }
65        }
66    };
67}
68
69/// Asserts that the first expression is greater than or equal to the second on debug builds.
70///
71/// This macro behaves the same as [`assert_ge!`] on debug builds. On release builds it is a no-op.
72#[macro_export]
73macro_rules! debug_assert_ge {
74    ($($arg:tt)*) => {
75        #[cfg(debug_assertions)]
76        $crate::assert_ge!($($arg)*);
77    }
78}
79
80#[cfg(test)]
81mod tests {
82    #[test]
83    fn greater_than() {
84        assert_ge!(5, 3);
85    }
86
87    #[test]
88    fn equal() {
89        assert_ge!(3, 3);
90    }
91
92    #[test]
93    #[should_panic(
94        expected = "assertion failed: `(left >= right)`\n    left: `1`,\n    right: `3`"
95    )]
96    fn less_than() {
97        assert_ge!(1, 3);
98    }
99
100    #[test]
101    #[should_panic(
102        expected = "assertion failed: `(left >= right)`\n    left: `1`,\n    right: `3`: foo"
103    )]
104    fn less_than_custom_message() {
105        assert_ge!(1, 3, "foo");
106    }
107
108    #[test]
109    #[cfg_attr(not(debug_assertions), ignore = "only run in debug mode")]
110    fn debug_greater_than() {
111        debug_assert_ge!(5, 3);
112    }
113
114    #[test]
115    #[cfg_attr(not(debug_assertions), ignore = "only run in debug mode")]
116    fn debug_equal() {
117        debug_assert_ge!(3, 3);
118    }
119
120    #[test]
121    #[cfg_attr(not(debug_assertions), ignore = "only run in debug mode")]
122    #[should_panic(
123        expected = "assertion failed: `(left >= right)`\n    left: `1`,\n    right: `3`"
124    )]
125    fn debug_less_than() {
126        debug_assert_ge!(1, 3);
127    }
128
129    #[test]
130    #[cfg_attr(not(debug_assertions), ignore = "only run in debug mode")]
131    #[should_panic(
132        expected = "assertion failed: `(left >= right)`\n    left: `1`,\n    right: `3`: foo"
133    )]
134    fn debug_less_than_custom_message() {
135        debug_assert_ge!(1, 3, "foo");
136    }
137
138    #[test]
139    #[cfg_attr(debug_assertions, ignore = "only run in release mode")]
140    fn debug_release_less_than() {
141        debug_assert_ge!(1, 3);
142    }
143}