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}