Skip to main content

assertables/assert_is_empty/
assert_is_empty.rs

1//! Assert an expression (such as a string or array) is empty.
2//!
3//! Pseudocode:<br>
4//! a.is_empty()
5//!
6//! # Example
7//!
8//! ```rust
9//! use assertables::*;
10//!
11//! let a = "";
12//! assert_is_empty!(a);
13//! ```
14//!
15//! # Module macros
16//!
17//! * [`assert_is_empty`](macro@crate::assert_is_empty)
18//! * [`assert_is_empty_as_result`](macro@crate::assert_is_empty_as_result)
19//! * [`debug_assert_is_empty`](macro@crate::debug_assert_is_empty)
20
21/// Assert an expression (such as a regex) is a match for an expression (such as a string).
22///
23/// Pseudocode:<br>
24/// a.is_empty()
25///
26/// * If true, return Result `Ok(())`.
27///
28/// * Otherwise, return Result `Err(message)`.
29///
30/// This macro is useful for runtime checks, such as checking parameters,
31/// or sanitizing inputs, or handling different results in different ways.
32///
33/// # Module macros
34///
35/// * [`assert_is_empty`](macro@crate::assert_is_empty)
36/// * [`assert_is_empty_as_result`](macro@crate::assert_is_empty_as_result)
37/// * [`debug_assert_is_empty`](macro@crate::debug_assert_is_empty)
38///
39#[macro_export]
40macro_rules! assert_is_empty_as_result {
41    ($a:expr $(,)?) => {
42        match (&$a) {
43            a => {
44                if a.is_empty() {
45                    Ok(())
46                } else {
47                    Err(format!(
48                        concat!(
49                            "assertion failed: `assert_is_empty!(a)`\n",
50                            "https://docs.rs/assertables/9.8.6/assertables/macro.assert_is_empty.html\n",
51                            " label: `{}`,\n",
52                            " debug: `{:?}`",
53                        ),
54                        stringify!($a),
55                        a,
56                    ))
57                }
58            }
59        }
60    };
61}
62
63#[cfg(test)]
64mod test_assert_is_empty_as_result {
65    use std::sync::Once;
66
67    #[test]
68    fn success() {
69        let a = "";
70        for _ in 0..1 {
71            let actual = assert_is_empty_as_result!(a);
72            assert_eq!(actual.unwrap(), ());
73        }
74    }
75
76    #[test]
77    fn success_once() {
78        static A: Once = Once::new();
79        fn a() -> &'static str {
80            if A.is_completed() {
81                panic!("A.is_completed()")
82            } else {
83                A.call_once(|| {})
84            }
85            ""
86        }
87
88        assert_eq!(A.is_completed(), false);
89        let result = assert_is_empty_as_result!(a());
90        assert!(result.is_ok());
91        assert_eq!(A.is_completed(), true);
92    }
93
94    #[test]
95    fn failure() {
96        let a = "alfa";
97        let actual = assert_is_empty_as_result!(a);
98        let message = concat!(
99            "assertion failed: `assert_is_empty!(a)`\n",
100            "https://docs.rs/assertables/9.8.6/assertables/macro.assert_is_empty.html\n",
101            " label: `a`,\n",
102            " debug: `\"alfa\"`"
103        );
104        assert_eq!(actual.unwrap_err(), message);
105    }
106}
107
108/// Assert an expression (such as a string or array) is empty.
109///
110/// Pseudocode:<br>
111/// a.is_empty()
112///
113/// * If true, return `()`.
114///
115/// * Otherwise, call [`panic!`] with a message and the values of the
116///   expressions with their debug representations.
117///
118/// # Examples
119///
120/// ```rust
121/// use assertables::*;
122/// # use std::panic;
123///
124/// # fn main() {
125/// let a = "";
126/// assert_is_empty!(a);
127///
128/// # let result = panic::catch_unwind(|| {
129/// // This will panic
130/// let a = "alfa";
131/// assert_is_empty!(a);
132/// # });
133/// // assertion failed: `assert_is_empty!(a)`
134/// // https://docs.rs/assertables/…/assertables/macro.assert_is_empty.html
135/// //  label: `a`,
136/// //  debug: `\"alfa\"`
137/// # let actual = result.unwrap_err().downcast::<String>().unwrap().to_string();
138/// # let message = concat!(
139/// #     "assertion failed: `assert_is_empty!(a)`\n",
140/// #     "https://docs.rs/assertables/9.8.6/assertables/macro.assert_is_empty.html\n",
141/// #     " label: `a`,\n",
142/// #     " debug: `\"alfa\"`"
143/// # );
144/// # assert_eq!(actual, message);
145/// # }
146/// ```
147///
148/// # Module macros
149///
150/// * [`assert_is_empty`](macro@crate::assert_is_empty)
151/// * [`assert_is_empty_as_result`](macro@crate::assert_is_empty_as_result)
152/// * [`debug_assert_is_empty`](macro@crate::debug_assert_is_empty)
153///
154#[macro_export]
155macro_rules! assert_is_empty {
156    ($a:expr $(,)?) => {
157        match $crate::assert_is_empty_as_result!($a) {
158            Ok(()) => (),
159            Err(err) => panic!("{}", err),
160        }
161    };
162    ($a:expr, $($message:tt)+) => {
163        match $crate::assert_is_empty_as_result!($a) {
164            Ok(()) => (),
165            Err(err) => panic!("{}\n{}", format_args!($($message)+), err),
166        }
167    };
168}
169
170#[cfg(test)]
171mod test_assert_is_empty {
172    use std::panic;
173
174    #[test]
175    fn success() {
176        let a = "";
177        for _ in 0..1 {
178            let actual = assert_is_empty!(a);
179            assert_eq!(actual, ());
180        }
181    }
182
183    #[test]
184    fn failure() {
185        let a = "alfa";
186        let result = panic::catch_unwind(|| {
187            let _actual = assert_is_empty!(a);
188        });
189        let message = concat!(
190            "assertion failed: `assert_is_empty!(a)`\n",
191            "https://docs.rs/assertables/9.8.6/assertables/macro.assert_is_empty.html\n",
192            " label: `a`,\n",
193            " debug: `\"alfa\"`"
194        );
195        assert_eq!(
196            result
197                .unwrap_err()
198                .downcast::<String>()
199                .unwrap()
200                .to_string(),
201            message
202        );
203    }
204}
205
206/// Assert an expression (such as a string or array) is empty.
207///
208/// Pseudocode:<br>
209/// a.is_empty()
210///
211/// This macro provides the same statements as [`assert_is_empty`](macro.assert_is_empty.html),
212/// except this macro's statements are only enabled in non-optimized
213/// builds by default. An optimized build will not execute this macro's
214/// statements unless `-C debug-assertions` is passed to the compiler.
215///
216/// This macro is useful for checks that are too expensive to be present
217/// in a release build but may be helpful during development.
218///
219/// The result of expanding this macro is always type checked.
220///
221/// An unchecked assertion allows a program in an inconsistent state to
222/// keep running, which might have unexpected consequences but does not
223/// introduce unsafety as long as this only happens in safe code. The
224/// performance cost of assertions, however, is not measurable in general.
225/// Replacing `assert*!` with `debug_assert*!` is thus only encouraged
226/// after thorough profiling, and more importantly, only in safe code!
227///
228/// This macro is intended to work in a similar way to
229/// [`::std::debug_assert`](https://doc.rust-lang.org/std/macro.debug_assert.html).
230///
231/// # Module macros
232///
233/// * [`assert_is_empty`](macro@crate::assert_is_empty)
234/// * [`assert_is_empty`](macro@crate::assert_is_empty)
235/// * [`debug_assert_is_empty`](macro@crate::debug_assert_is_empty)
236///
237#[macro_export]
238macro_rules! debug_assert_is_empty {
239    ($($arg:tt)*) => {
240        if cfg!(debug_assertions) {
241            $crate::assert_is_empty!($($arg)*);
242        }
243    };
244}
245
246#[cfg(test)]
247mod test_debug_assert_is_empty {
248    use std::panic;
249
250    #[test]
251    fn success() {
252        let a = "";
253        for _ in 0..1 {
254            let _actual = debug_assert_is_empty!(a);
255            // assert_eq!(actual, ());
256        }
257    }
258
259    #[test]
260    fn failure() {
261        let a = "alfa";
262        let result = panic::catch_unwind(|| {
263            let _actual = debug_assert_is_empty!(a);
264        });
265        let message = concat!(
266            "assertion failed: `assert_is_empty!(a)`\n",
267            "https://docs.rs/assertables/9.8.6/assertables/macro.assert_is_empty.html\n",
268            " label: `a`,\n",
269            " debug: `\"alfa\"`"
270        );
271        assert_eq!(
272            result
273                .unwrap_err()
274                .downcast::<String>()
275                .unwrap()
276                .to_string(),
277            message
278        );
279    }
280}