assertables/assert_fn_ok/assert_fn_ok_gt.rs
1//! Assert a function Ok(…) is greater than another.
2//!
3//! Pseudocode:<br>
4//! (a_function(a_param) ⇒ Ok(a) ⇒ a) > (b_function(b_param) ⇒ Ok(b) ⇒ b)
5//!
6//! # Example
7//!
8//! ```rust
9//! use assertables::*;
10//! fn f(i: i8) -> Result<String, String> {
11//! match i {
12//! 0..=9 => Ok(format!("{}", i)),
13//! _ => Err(format!("{:?} is out of range", i)),
14//! }
15//! }
16//!
17//! let a: i8 = 2;
18//! let b: i8 = 1;
19//! assert_fn_ok_gt!(f, a, f, b);
20//! ```
21//!
22//! # Module macros
23//!
24//! * [`assert_fn_ok_gt`](macro@crate::assert_fn_ok_gt)
25//! * [`assert_fn_ok_gt_as_result`](macro@crate::assert_fn_ok_gt_as_result)
26//! * [`debug_assert_fn_ok_gt`](macro@crate::debug_assert_fn_ok_gt)
27
28/// Assert a function Ok(…) is greater than another.
29///
30/// Pseudocode:<br>
31/// (a_function(a_param) ⇒ Ok(a) ⇒ a) > (b_function(b_param) ⇒ Ok(b) ⇒ b)
32///
33/// * If true, return Result `Ok(a, b)`.
34///
35/// * Otherwise, return Result `Err(message)`.
36///
37/// This macro is useful for runtime checks, such as checking parameters,
38/// or sanitizing inputs, or handling different results in different ways.
39///
40/// # Module macros
41///
42/// * [`assert_fn_ok_gt`](macro@crate::assert_fn_ok_gt)
43/// * [`assert_fn_ok_gt_as_result`](macro@crate::assert_fn_ok_gt_as_result)
44/// * [`debug_assert_fn_ok_gt`](macro@crate::debug_assert_fn_ok_gt)
45///
46#[macro_export]
47macro_rules! assert_fn_ok_gt_as_result {
48
49 //// Arity 1
50
51 ($a_function:path, $a_param:expr, $b_function:path, $b_param:expr $(,)?) => {
52 match (&$a_function, &$a_param, &$b_function, &$b_param) {
53 (_a_function, a_param, _b_function, b_param) => {
54 match (
55 $a_function($a_param),
56 $b_function($b_param)
57 ) {
58 (Ok(a), Ok(b)) => {
59 if a > b {
60 Ok((a, b))
61 } else {
62 Err(
63 format!(
64 concat!(
65 "assertion failed: `assert_fn_ok_gt!(a_function, a_param, b_function, b_param)`\n",
66 "https://docs.rs/assertables/9.6.0/assertables/macro.assert_fn_ok_gt.html\n",
67 " a_function label: `{}`,\n",
68 " a_param label: `{}`,\n",
69 " a_param debug: `{:?}`,\n",
70 " b_function label: `{}`,\n",
71 " b_param label: `{}`,\n",
72 " b_param debug: `{:?}`,\n",
73 " a: `{:?}`,\n",
74 " b: `{:?}`"
75 ),
76 stringify!($a_function),
77 stringify!($a_param),
78 a_param,
79 stringify!($b_function),
80 stringify!($b_param),
81 b_param,
82 a,
83 b
84 )
85 )
86 }
87 },
88 (a, b) => {
89 Err(
90 format!(
91 concat!(
92 "assertion failed: `assert_fn_err_gt!(a_function, a_param, b_function, b_param)`\n",
93 "https://docs.rs/assertables/9.6.0/assertables/macro.assert_fn_err_gt.html\n",
94 " a_function label: `{}`,\n",
95 " a_param label: `{}`,\n",
96 " a_param debug: `{:?}`,\n",
97 " b_function label: `{}`,\n",
98 " b_param label: `{}`,\n",
99 " b_param debug: `{:?}`,\n",
100 " a: `{:?}`,\n",
101 " b: `{:?}`"
102 ),
103 stringify!($a_function),
104 stringify!($a_param),
105 a_param,
106 stringify!($b_function),
107 stringify!($b_param),
108 b_param,
109 a,
110 b
111 )
112 )
113 }
114 }
115 }
116 }
117 };
118
119 //// Arity 0
120
121 ($a_function:path, $b_function:path) => {
122 match (
123 $a_function(),
124 $b_function()
125 ) {
126 (Ok(a), Ok(b)) => {
127 if a > b {
128 Ok((a, b))
129 } else {
130 Err(
131 format!(
132 concat!(
133 "assertion failed: `assert_fn_ok_gt!(a_function, b_function)`\n",
134 "https://docs.rs/assertables/9.6.0/assertables/macro.assert_fn_ok_gt.html\n",
135 " a_function label: `{}`,\n",
136 " b_function label: `{}`,\n",
137 " a: `{:?}`,\n",
138 " b: `{:?}`"
139 ),
140 stringify!($a_function),
141 stringify!($b_function),
142 a,
143 b
144 )
145 )
146 }
147 },
148 (a, b) => {
149 Err(
150 format!(
151 concat!(
152 "assertion failed: `assert_fn_err_gt!(a_function, b_function)`\n",
153 "https://docs.rs/assertables/9.6.0/assertables/macro.assert_fn_err_gt.html\n",
154 " a_function label: `{}`,\n",
155 " b_function label: `{}`,\n",
156 " a: `{:?}`,\n",
157 " b: `{:?}`"
158 ),
159 stringify!($a_function),
160 stringify!($b_function),
161 a,
162 b
163 )
164 )
165 }
166 }
167 };
168
169}
170
171#[cfg(test)]
172mod test_assert_fn_ok_gt_as_result {
173 use std::sync::Once;
174
175 mod arity_1 {
176
177 fn f(i: i8) -> Result<i8, i8> {
178 return Ok(i);
179 }
180
181 fn g(i: i8) -> Result<i8, i8> {
182 return Ok(i);
183 }
184
185 #[test]
186 fn gt() {
187 let a: i8 = 2;
188 let b: i8 = 1;
189 let actual = assert_fn_ok_gt_as_result!(f, a, g, b);
190 assert_eq!(actual.unwrap(), (2, 1));
191 }
192
193 #[test]
194 fn eq() {
195 let a: i8 = 1;
196 let b: i8 = 1;
197 let actual = assert_fn_ok_gt_as_result!(f, a, g, b);
198 let message = concat!(
199 "assertion failed: `assert_fn_ok_gt!(a_function, a_param, b_function, b_param)`\n",
200 "https://docs.rs/assertables/9.6.0/assertables/macro.assert_fn_ok_gt.html\n",
201 " a_function label: `f`,\n",
202 " a_param label: `a`,\n",
203 " a_param debug: `1`,\n",
204 " b_function label: `g`,\n",
205 " b_param label: `b`,\n",
206 " b_param debug: `1`,\n",
207 " a: `1`,\n",
208 " b: `1`"
209 );
210 assert_eq!(actual.unwrap_err(), message);
211 }
212
213 #[test]
214 fn lt() {
215 let a: i8 = 1;
216 let b: i8 = 2;
217 let actual = assert_fn_ok_gt_as_result!(f, a, g, b);
218 let message = concat!(
219 "assertion failed: `assert_fn_ok_gt!(a_function, a_param, b_function, b_param)`\n",
220 "https://docs.rs/assertables/9.6.0/assertables/macro.assert_fn_ok_gt.html\n",
221 " a_function label: `f`,\n",
222 " a_param label: `a`,\n",
223 " a_param debug: `1`,\n",
224 " b_function label: `g`,\n",
225 " b_param label: `b`,\n",
226 " b_param debug: `2`,\n",
227 " a: `1`,\n",
228 " b: `2`"
229 );
230 assert_eq!(actual.unwrap_err(), message);
231 }
232 }
233
234 mod arity_0 {
235
236 fn f() -> Result<i8, i8> {
237 return Ok(1);
238 }
239
240 fn g() -> Result<i8, i8> {
241 return Ok(2);
242 }
243
244 #[test]
245 fn gt() {
246 let actual = assert_fn_ok_gt_as_result!(g, f);
247 assert_eq!(actual.unwrap(), (2, 1));
248 }
249
250 #[test]
251 fn eq() {
252 let actual = assert_fn_ok_gt_as_result!(f, f);
253 let message = concat!(
254 "assertion failed: `assert_fn_ok_gt!(a_function, b_function)`\n",
255 "https://docs.rs/assertables/9.6.0/assertables/macro.assert_fn_ok_gt.html\n",
256 " a_function label: `f`,\n",
257 " b_function label: `f`,\n",
258 " a: `1`,\n",
259 " b: `1`"
260 );
261 assert_eq!(actual.unwrap_err(), message);
262 }
263
264 #[test]
265 fn lt() {
266 let actual = assert_fn_ok_gt_as_result!(f, g);
267 let message = concat!(
268 "assertion failed: `assert_fn_ok_gt!(a_function, b_function)`\n",
269 "https://docs.rs/assertables/9.6.0/assertables/macro.assert_fn_ok_gt.html\n",
270 " a_function label: `f`,\n",
271 " b_function label: `g`,\n",
272 " a: `1`,\n",
273 " b: `2`"
274 );
275 assert_eq!(actual.unwrap_err(), message);
276 }
277 }
278}
279
280/// Assert a function Ok(…) is greater than another.
281///
282/// Pseudocode:<br>
283/// (a_function(a_param) ⇒ Ok(a) ⇒ a) > (b_function(b_param) ⇒ Ok(b) ⇒ b)
284///
285/// * If true, return `(a, b)`.
286///
287/// * Otherwise, call [`panic!`] with a message and the values of the
288/// expressions with their debug representations.
289///
290/// # Examples
291///
292/// ```rust
293/// use assertables::*;
294/// # use std::panic;
295/// fn f(i: i8) -> Result<String, String> {
296/// match i {
297/// 0..=9 => Ok(format!("{}", i)),
298/// _ => Err(format!("{:?} is out of range", i)),
299/// }
300/// }
301///
302/// # fn main() {
303/// let a: i8 = 2;
304/// let b: i8 = 1;
305/// assert_fn_ok_gt!(f, a, f, b);
306///
307/// # let result = panic::catch_unwind(|| {
308/// // This will panic
309/// let a: i8 = 1;
310/// let b: i8 = 2;
311/// assert_fn_ok_gt!(f, a, f, b);
312/// # });
313/// // assertion failed: `assert_fn_ok_gt!(a_function, a_param, b_function, b_param)`
314/// // https://docs.rs/assertables/9.6.0/assertables/macro.assert_fn_ok_gt.html
315/// // a_function label: `f`,
316/// // a_param label: `a`,
317/// // a_param debug: `1`,
318/// // b_function label: `f`,
319/// // b_param label: `b`,
320/// // b_param debug: `2`,
321/// // a: `\"1\"`,
322/// // b: `\"2\"`
323/// # let actual = result.unwrap_err().downcast::<String>().unwrap().to_string();
324/// # let message = concat!(
325/// # "assertion failed: `assert_fn_ok_gt!(a_function, a_param, b_function, b_param)`\n",
326/// # "https://docs.rs/assertables/9.6.0/assertables/macro.assert_fn_ok_gt.html\n",
327/// # " a_function label: `f`,\n",
328/// # " a_param label: `a`,\n",
329/// # " a_param debug: `1`,\n",
330/// # " b_function label: `f`,\n",
331/// # " b_param label: `b`,\n",
332/// # " b_param debug: `2`,\n",
333/// # " a: `\"1\"`,\n",
334/// # " b: `\"2\"`"
335/// # );
336/// # assert_eq!(actual, message);
337/// # }
338/// ```
339///
340/// # Module macros
341///
342/// * [`assert_fn_ok_gt`](macro@crate::assert_fn_ok_gt)
343/// * [`assert_fn_ok_gt_as_result`](macro@crate::assert_fn_ok_gt_as_result)
344/// * [`debug_assert_fn_ok_gt`](macro@crate::debug_assert_fn_ok_gt)
345///
346#[macro_export]
347macro_rules! assert_fn_ok_gt {
348
349 //// Arity 1
350
351 ($a_function:path, $a_param:expr, $b_function:path, $b_param:expr $(,)?) => {
352 match $crate::assert_fn_ok_gt_as_result!($a_function, $a_param, $b_function, $b_param) {
353 Ok(x) => x,
354 Err(err) => panic!("{}", err),
355 }
356 };
357
358 ($a_function:path, $a_param:expr, $b_function:path, $b_param:expr, $($message:tt)+) => {
359 match $crate::assert_fn_ok_gt_as_result!($a_function, $a_param, $b_function, $b_param) {
360 Ok(x) => x,
361 Err(err) => panic!("{}\n{}", format_args!($($message)+), err),
362 }
363 };
364
365 //// Arity 0
366
367 ($a_function:path, $b_function:path) => {
368 match $crate::assert_fn_ok_gt_as_result!($a_function, $b_function) {
369 Ok(x) => x,
370 Err(err) => panic!("{}", err),
371 }
372 };
373
374 ($a_function:path, $b_function:path, $($message:tt)+) => {
375 match $crate::assert_fn_ok_gt_as_result!($a_function, $b_function) {
376 Ok(x) => x,
377 Err(err) => panic!("{}\n{}", format_args!($($message)+), err),
378 }
379 };
380}
381
382#[cfg(test)]
383mod test_assert_fn_ok_gt {
384 use std::panic;
385
386 mod arity_1 {
387 use super::*;
388
389 fn f(i: i8) -> Result<i8, i8> {
390 return Ok(i);
391 }
392
393 fn g(i: i8) -> Result<i8, i8> {
394 return Ok(i);
395 }
396
397 #[test]
398 fn gt() {
399 let a: i8 = 2;
400 let b: i8 = 1;
401 let actual = assert_fn_ok_gt!(f, a, g, b);
402 assert_eq!(actual, (2, 1));
403 }
404
405 #[test]
406 fn eq() {
407 let result = panic::catch_unwind(|| {
408 let a: i8 = 1;
409 let b: i8 = 1;
410 let _actual = assert_fn_ok_gt!(f, a, g, b);
411 });
412 let message = concat!(
413 "assertion failed: `assert_fn_ok_gt!(a_function, a_param, b_function, b_param)`\n",
414 "https://docs.rs/assertables/9.6.0/assertables/macro.assert_fn_ok_gt.html\n",
415 " a_function label: `f`,\n",
416 " a_param label: `a`,\n",
417 " a_param debug: `1`,\n",
418 " b_function label: `g`,\n",
419 " b_param label: `b`,\n",
420 " b_param debug: `1`,\n",
421 " a: `1`,\n",
422 " b: `1`"
423 );
424 assert_eq!(
425 result
426 .unwrap_err()
427 .downcast::<String>()
428 .unwrap()
429 .to_string(),
430 message
431 );
432 }
433
434 #[test]
435 fn lt() {
436 let result = panic::catch_unwind(|| {
437 let a: i8 = 1;
438 let b: i8 = 2;
439 let _actual = assert_fn_ok_gt!(f, a, g, b);
440 });
441 let message = concat!(
442 "assertion failed: `assert_fn_ok_gt!(a_function, a_param, b_function, b_param)`\n",
443 "https://docs.rs/assertables/9.6.0/assertables/macro.assert_fn_ok_gt.html\n",
444 " a_function label: `f`,\n",
445 " a_param label: `a`,\n",
446 " a_param debug: `1`,\n",
447 " b_function label: `g`,\n",
448 " b_param label: `b`,\n",
449 " b_param debug: `2`,\n",
450 " a: `1`,\n",
451 " b: `2`"
452 );
453 assert_eq!(
454 result
455 .unwrap_err()
456 .downcast::<String>()
457 .unwrap()
458 .to_string(),
459 message
460 );
461 }
462 }
463
464 mod arity_0 {
465 use super::*;
466
467 fn f() -> Result<i8, i8> {
468 return Ok(1);
469 }
470
471 fn g() -> Result<i8, i8> {
472 return Ok(2);
473 }
474
475 #[test]
476 fn gt() {
477 let actual = assert_fn_ok_gt!(g, f);
478 assert_eq!(actual, (2, 1));
479 }
480
481 #[test]
482 fn eq() {
483 let result = panic::catch_unwind(|| {
484 let _actual = assert_fn_ok_gt!(f, f);
485 });
486 let message = concat!(
487 "assertion failed: `assert_fn_ok_gt!(a_function, b_function)`\n",
488 "https://docs.rs/assertables/9.6.0/assertables/macro.assert_fn_ok_gt.html\n",
489 " a_function label: `f`,\n",
490 " b_function label: `f`,\n",
491 " a: `1`,\n",
492 " b: `1`"
493 );
494 assert_eq!(
495 result
496 .unwrap_err()
497 .downcast::<String>()
498 .unwrap()
499 .to_string(),
500 message
501 );
502 }
503
504 #[test]
505 fn lt() {
506 let result = panic::catch_unwind(|| {
507 let _actual = assert_fn_ok_gt!(f, g);
508 });
509 let message = concat!(
510 "assertion failed: `assert_fn_ok_gt!(a_function, b_function)`\n",
511 "https://docs.rs/assertables/9.6.0/assertables/macro.assert_fn_ok_gt.html\n",
512 " a_function label: `f`,\n",
513 " b_function label: `g`,\n",
514 " a: `1`,\n",
515 " b: `2`"
516 );
517 assert_eq!(
518 result
519 .unwrap_err()
520 .downcast::<String>()
521 .unwrap()
522 .to_string(),
523 message
524 );
525 }
526 }
527}
528
529/// Assert a function Ok(…) is greater than another.
530///
531/// Pseudocode:<br>
532/// (a_function(a_param) ⇒ Ok(a) ⇒ a) > (b_function(b_param) ⇒ Ok(b) ⇒ b)
533///
534/// This macro provides the same statements as [`assert_fn_ok_gt`](macro.assert_fn_ok_gt.html),
535/// except this macro's statements are only enabled in non-optimized
536/// builds by default. An optimized build will not execute this macro's
537/// statements unless `-C debug-assertions` is passed to the compiler.
538///
539/// This macro is useful for checks that are too expensive to be present
540/// in a release build but may be helpful during development.
541///
542/// The result of expanding this macro is always type checked.
543///
544/// An unchecked assertion allows a program in an inconsistent state to
545/// keep running, which might have unexpected consequences but does not
546/// introduce unsafety as long as this only happens in safe code. The
547/// performance cost of assertions, however, is not measurable in general.
548/// Replacing `assert*!` with `debug_assert*!` is thus only encouraged
549/// after thorough profiling, and more importantly, only in safe code!
550///
551/// This macro is intended to work in a similar way to
552/// [`::std::debug_assert`](https://doc.rust-lang.org/std/macro.debug_assert.html).
553///
554/// # Module macros
555///
556/// * [`assert_fn_ok_gt`](macro@crate::assert_fn_ok_gt)
557/// * [`assert_fn_ok_gt`](macro@crate::assert_fn_ok_gt)
558/// * [`debug_assert_fn_ok_gt`](macro@crate::debug_assert_fn_ok_gt)
559///
560#[macro_export]
561macro_rules! debug_assert_fn_ok_gt {
562 ($($arg:tt)*) => {
563 if $crate::cfg!(debug_assertions) {
564 $crate::assert_fn_ok_gt!($($arg)*);
565 }
566 };
567}