assertables/assert_is_empty/
assert_not_empty.rs

1//! Assert an expression (such as a string or array) is not empty.
2//!
3//! Pseudocode:<br>
4//! ¬ a.is_empty()
5//!
6//! # Example
7//!
8//! ```rust
9//! use assertables::*;
10//!
11//! let a = "alfa";
12//! assert_not_empty!(a);
13//! ```
14//!
15//! # Module macros
16//!
17//! * [`assert_not_empty`](macro@crate::assert_not_empty)
18//! * [`assert_not_empty_as_result`](macro@crate::assert_not_empty_as_result)
19//! * [`debug_assert_not_empty`](macro@crate::debug_assert_not_empty)
20
21/// Assert an expression (such as a string or array) is not empty.
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_not_empty`](macro@crate::assert_not_empty)
36/// * [`assert_not_empty_as_result`](macro@crate::assert_not_empty_as_result)
37/// * [`debug_assert_not_empty`](macro@crate::debug_assert_not_empty)
38///
39#[macro_export]
40macro_rules! assert_not_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_not_empty!(a)`\n",
50                            "https://docs.rs/assertables/9.8.3/assertables/macro.assert_not_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_not_empty_as_result {
65    use std::sync::Once;
66
67    #[test]
68    fn success() {
69        let a = "alfa";
70        for _ in 0..1 {
71            let actual = assert_not_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            "alfa"
86        }
87
88        assert_eq!(A.is_completed(), false);
89        let result = assert_not_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 = "";
97        let actual = assert_not_empty_as_result!(a);
98        let message = concat!(
99            "assertion failed: `assert_not_empty!(a)`\n",
100            "https://docs.rs/assertables/9.8.3/assertables/macro.assert_not_empty.html\n",
101            " label: `a`,\n",
102            " debug: `\"\"`",
103        );
104        assert_eq!(actual.unwrap_err(), message);
105    }
106}
107
108/// Assert an expression (such as a string or array) is not 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 = "alfa";
126/// assert_not_empty!(a);
127///
128/// # let result = panic::catch_unwind(|| {
129/// // This will panic
130/// let a = "";
131/// assert_not_empty!(a);
132/// # });
133/// // assertion failed: `assert_not_empty!(a)`
134/// // https://docs.rs/assertables/…/assertables/macro.assert_not_empty.html
135/// //  label: `a`,
136/// //  debug: `\"\"`
137/// # let actual = result.unwrap_err().downcast::<String>().unwrap().to_string();
138/// # let message = concat!(
139/// #     "assertion failed: `assert_not_empty!(a)`\n",
140/// #     "https://docs.rs/assertables/9.8.3/assertables/macro.assert_not_empty.html\n",
141/// #     " label: `a`,\n",
142/// #     " debug: `\"\"`"
143/// # );
144/// # assert_eq!(actual, message);
145/// # }
146/// ```
147///
148/// # Module macros
149///
150/// * [`assert_not_empty`](macro@crate::assert_not_empty)
151/// * [`assert_not_empty_as_result`](macro@crate::assert_not_empty_as_result)
152/// * [`debug_assert_not_empty`](macro@crate::debug_assert_not_empty)
153///
154#[macro_export]
155macro_rules! assert_not_empty {
156    ($a:expr $(,)?) => {
157        match $crate::assert_not_empty_as_result!($a) {
158            Ok(()) => (),
159            Err(err) => panic!("{}", err),
160        }
161    };
162    ($a:expr, $($message:tt)+) => {
163        match $crate::assert_not_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_not_empty {
172    use std::panic;
173
174    #[test]
175    fn success() {
176        let a = "alfa";
177        for _ in 0..1 {
178            let actual = assert_not_empty!(a);
179            assert_eq!(actual, ());
180        }
181    }
182
183    #[test]
184    fn failure() {
185        let a = "";
186        let result = panic::catch_unwind(|| {
187            let _actual = assert_not_empty!(a);
188        });
189        let message = concat!(
190            "assertion failed: `assert_not_empty!(a)`\n",
191            "https://docs.rs/assertables/9.8.3/assertables/macro.assert_not_empty.html\n",
192            " label: `a`,\n",
193            " debug: `\"\"`",
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 not empty.
207///
208/// Pseudocode:<br>
209/// ¬ a.is_empty()
210///
211/// This macro provides the same statements as [`assert_not_empty`](macro.assert_not_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_not_empty`](macro@crate::assert_not_empty)
234/// * [`assert_not_empty`](macro@crate::assert_not_empty)
235/// * [`debug_assert_not_empty`](macro@crate::debug_assert_not_empty)
236///
237#[macro_export]
238macro_rules! debug_assert_not_empty {
239    ($($arg:tt)*) => {
240        if $crate::cfg!(debug_assertions) {
241            $crate::assert_not_empty!($($arg)*);
242        }
243    };
244}