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.5.4/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.5.4/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.5.4/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.5.4/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
174    mod arity_1 {
175
176        fn f(i: i8) -> Result<i8, i8> {
177            return Ok(i);
178        }
179
180        fn g(i: i8) -> Result<i8, i8> {
181            return Ok(i);
182        }
183
184        #[test]
185        fn gt() {
186            let a: i8 = 2;
187            let b: i8 = 1;
188            let actual = assert_fn_ok_gt_as_result!(f, a, g, b);
189            assert_eq!(actual.unwrap(), (2, 1));
190        }
191
192        #[test]
193        fn eq() {
194            let a: i8 = 1;
195            let b: i8 = 1;
196            let actual = assert_fn_ok_gt_as_result!(f, a, g, b);
197            let message = concat!(
198                "assertion failed: `assert_fn_ok_gt!(a_function, a_param, b_function, b_param)`\n",
199                "https://docs.rs/assertables/9.5.4/assertables/macro.assert_fn_ok_gt.html\n",
200                " a_function label: `f`,\n",
201                "    a_param label: `a`,\n",
202                "    a_param debug: `1`,\n",
203                " b_function label: `g`,\n",
204                "    b_param label: `b`,\n",
205                "    b_param debug: `1`,\n",
206                "                a: `1`,\n",
207                "                b: `1`"
208            );
209            assert_eq!(actual.unwrap_err(), message);
210        }
211
212        #[test]
213        fn lt() {
214            let a: i8 = 1;
215            let b: i8 = 2;
216            let actual = assert_fn_ok_gt_as_result!(f, a, g, b);
217            let message = concat!(
218                "assertion failed: `assert_fn_ok_gt!(a_function, a_param, b_function, b_param)`\n",
219                "https://docs.rs/assertables/9.5.4/assertables/macro.assert_fn_ok_gt.html\n",
220                " a_function label: `f`,\n",
221                "    a_param label: `a`,\n",
222                "    a_param debug: `1`,\n",
223                " b_function label: `g`,\n",
224                "    b_param label: `b`,\n",
225                "    b_param debug: `2`,\n",
226                "                a: `1`,\n",
227                "                b: `2`"
228            );
229            assert_eq!(actual.unwrap_err(), message);
230        }
231    }
232
233    mod arity_0 {
234
235        fn f() -> Result<i8, i8> {
236            return Ok(1);
237        }
238
239        fn g() -> Result<i8, i8> {
240            return Ok(2);
241        }
242
243        #[test]
244        fn gt() {
245            let actual = assert_fn_ok_gt_as_result!(g, f);
246            assert_eq!(actual.unwrap(), (2, 1));
247        }
248
249        #[test]
250        fn eq() {
251            let actual = assert_fn_ok_gt_as_result!(f, f);
252            let message = concat!(
253                "assertion failed: `assert_fn_ok_gt!(a_function, b_function)`\n",
254                "https://docs.rs/assertables/9.5.4/assertables/macro.assert_fn_ok_gt.html\n",
255                " a_function label: `f`,\n",
256                " b_function label: `f`,\n",
257                "                a: `1`,\n",
258                "                b: `1`"
259            );
260            assert_eq!(actual.unwrap_err(), message);
261        }
262
263        #[test]
264        fn lt() {
265            let actual = assert_fn_ok_gt_as_result!(f, g);
266            let message = concat!(
267                "assertion failed: `assert_fn_ok_gt!(a_function, b_function)`\n",
268                "https://docs.rs/assertables/9.5.4/assertables/macro.assert_fn_ok_gt.html\n",
269                " a_function label: `f`,\n",
270                " b_function label: `g`,\n",
271                "                a: `1`,\n",
272                "                b: `2`"
273            );
274            assert_eq!(actual.unwrap_err(), message);
275        }
276    }
277}
278
279/// Assert a function Ok(…) is greater than another.
280///
281/// Pseudocode:<br>
282/// (a_function(a_param) ⇒ Ok(a) ⇒ a) > (b_function(b_param) ⇒ Ok(b) ⇒ b)
283///
284/// * If true, return `(a, b)`.
285///
286/// * Otherwise, call [`panic!`] with a message and the values of the
287///   expressions with their debug representations.
288///
289/// # Examples
290///
291/// ```rust
292/// use assertables::*;
293/// # use std::panic;
294/// fn f(i: i8) -> Result<String, String> {
295///     match i {
296///         0..=9 => Ok(format!("{}", i)),
297///         _ => Err(format!("{:?} is out of range", i)),
298///     }
299/// }
300///
301/// # fn main() {
302/// let a: i8 = 2;
303/// let b: i8 = 1;
304/// assert_fn_ok_gt!(f, a, f, b);
305///
306/// # let result = panic::catch_unwind(|| {
307/// // This will panic
308/// let a: i8 = 1;
309/// let b: i8 = 2;
310/// assert_fn_ok_gt!(f, a, f, b);
311/// # });
312/// // assertion failed: `assert_fn_ok_gt!(a_function, a_param, b_function, b_param)`
313/// // https://docs.rs/assertables/9.5.4/assertables/macro.assert_fn_ok_gt.html
314/// //  a_function label: `f`,
315/// //     a_param label: `a`,
316/// //     a_param debug: `1`,
317/// //  b_function label: `f`,
318/// //     b_param label: `b`,
319/// //     b_param debug: `2`,
320/// //                 a: `\"1\"`,
321/// //                 b: `\"2\"`
322/// # let actual = result.unwrap_err().downcast::<String>().unwrap().to_string();
323/// # let message = concat!(
324/// #     "assertion failed: `assert_fn_ok_gt!(a_function, a_param, b_function, b_param)`\n",
325/// #     "https://docs.rs/assertables/9.5.4/assertables/macro.assert_fn_ok_gt.html\n",
326/// #     " a_function label: `f`,\n",
327/// #     "    a_param label: `a`,\n",
328/// #     "    a_param debug: `1`,\n",
329/// #     " b_function label: `f`,\n",
330/// #     "    b_param label: `b`,\n",
331/// #     "    b_param debug: `2`,\n",
332/// #     "                a: `\"1\"`,\n",
333/// #     "                b: `\"2\"`"
334/// # );
335/// # assert_eq!(actual, message);
336/// # }
337/// ```
338///
339/// # Module macros
340///
341/// * [`assert_fn_ok_gt`](macro@crate::assert_fn_ok_gt)
342/// * [`assert_fn_ok_gt_as_result`](macro@crate::assert_fn_ok_gt_as_result)
343/// * [`debug_assert_fn_ok_gt`](macro@crate::debug_assert_fn_ok_gt)
344///
345#[macro_export]
346macro_rules! assert_fn_ok_gt {
347
348    //// Arity 1
349
350    ($a_function:path, $a_param:expr, $b_function:path, $b_param:expr $(,)?) => {{
351        match $crate::assert_fn_ok_gt_as_result!($a_function, $a_param, $b_function, $b_param) {
352            Ok(x) => x,
353            Err(err) => panic!("{}", err),
354        }
355    }};
356
357    ($a_function:path, $a_param:expr, $b_function:path, $b_param:expr, $($message:tt)+) => {{
358        match $crate::assert_fn_ok_gt_as_result!($a_function, $a_param, $b_function, $b_param) {
359            Ok(x) => x,
360            Err(err) => panic!("{}\n{}", format_args!($($message)+), err),
361        }
362    }};
363
364    //// Arity 0
365
366    ($a_function:path, $b_function:path) => {{
367        match $crate::assert_fn_ok_gt_as_result!($a_function, $b_function) {
368            Ok(x) => x,
369            Err(err) => panic!("{}", err),
370        }
371    }};
372
373    ($a_function:path, $b_function:path, $($message:tt)+) => {{
374        match $crate::assert_fn_ok_gt_as_result!($a_function, $b_function) {
375            Ok(x) => x,
376            Err(err) => panic!("{}\n{}", format_args!($($message)+), err),
377        }
378    }};
379}
380
381#[cfg(test)]
382mod test_assert_fn_ok_gt {
383    use std::panic;
384
385    mod arity_1 {
386        use super::*;
387
388        fn f(i: i8) -> Result<i8, i8> {
389            return Ok(i);
390        }
391
392        fn g(i: i8) -> Result<i8, i8> {
393            return Ok(i);
394        }
395
396        #[test]
397        fn gt() {
398            let a: i8 = 2;
399            let b: i8 = 1;
400            let actual = assert_fn_ok_gt!(f, a, g, b);
401            assert_eq!(actual, (2, 1));
402        }
403
404        #[test]
405        fn eq() {
406            let result = panic::catch_unwind(|| {
407                let a: i8 = 1;
408                let b: i8 = 1;
409                let _actual = assert_fn_ok_gt!(f, a, g, b);
410            });
411            let message = concat!(
412                "assertion failed: `assert_fn_ok_gt!(a_function, a_param, b_function, b_param)`\n",
413                "https://docs.rs/assertables/9.5.4/assertables/macro.assert_fn_ok_gt.html\n",
414                " a_function label: `f`,\n",
415                "    a_param label: `a`,\n",
416                "    a_param debug: `1`,\n",
417                " b_function label: `g`,\n",
418                "    b_param label: `b`,\n",
419                "    b_param debug: `1`,\n",
420                "                a: `1`,\n",
421                "                b: `1`"
422            );
423            assert_eq!(
424                result
425                    .unwrap_err()
426                    .downcast::<String>()
427                    .unwrap()
428                    .to_string(),
429                message
430            );
431        }
432
433        #[test]
434        fn lt() {
435            let result = panic::catch_unwind(|| {
436                let a: i8 = 1;
437                let b: i8 = 2;
438                let _actual = assert_fn_ok_gt!(f, a, g, b);
439            });
440            let message = concat!(
441                "assertion failed: `assert_fn_ok_gt!(a_function, a_param, b_function, b_param)`\n",
442                "https://docs.rs/assertables/9.5.4/assertables/macro.assert_fn_ok_gt.html\n",
443                " a_function label: `f`,\n",
444                "    a_param label: `a`,\n",
445                "    a_param debug: `1`,\n",
446                " b_function label: `g`,\n",
447                "    b_param label: `b`,\n",
448                "    b_param debug: `2`,\n",
449                "                a: `1`,\n",
450                "                b: `2`"
451            );
452            assert_eq!(
453                result
454                    .unwrap_err()
455                    .downcast::<String>()
456                    .unwrap()
457                    .to_string(),
458                message
459            );
460        }
461    }
462
463    mod arity_0 {
464        use super::*;
465
466        fn f() -> Result<i8, i8> {
467            return Ok(1);
468        }
469
470        fn g() -> Result<i8, i8> {
471            return Ok(2);
472        }
473
474        #[test]
475        fn gt() {
476            let actual = assert_fn_ok_gt!(g, f);
477            assert_eq!(actual, (2, 1));
478        }
479
480        #[test]
481        fn eq() {
482            let result = panic::catch_unwind(|| {
483                let _actual = assert_fn_ok_gt!(f, f);
484            });
485            let message = concat!(
486                "assertion failed: `assert_fn_ok_gt!(a_function, b_function)`\n",
487                "https://docs.rs/assertables/9.5.4/assertables/macro.assert_fn_ok_gt.html\n",
488                " a_function label: `f`,\n",
489                " b_function label: `f`,\n",
490                "                a: `1`,\n",
491                "                b: `1`"
492            );
493            assert_eq!(
494                result
495                    .unwrap_err()
496                    .downcast::<String>()
497                    .unwrap()
498                    .to_string(),
499                message
500            );
501        }
502
503        #[test]
504        fn lt() {
505            let result = panic::catch_unwind(|| {
506                let _actual = assert_fn_ok_gt!(f, g);
507            });
508            let message = concat!(
509                "assertion failed: `assert_fn_ok_gt!(a_function, b_function)`\n",
510                "https://docs.rs/assertables/9.5.4/assertables/macro.assert_fn_ok_gt.html\n",
511                " a_function label: `f`,\n",
512                " b_function label: `g`,\n",
513                "                a: `1`,\n",
514                "                b: `2`"
515            );
516            assert_eq!(
517                result
518                    .unwrap_err()
519                    .downcast::<String>()
520                    .unwrap()
521                    .to_string(),
522                message
523            );
524        }
525    }
526}
527
528/// Assert a function Ok(…) is greater than another.
529///
530/// Pseudocode:<br>
531/// (a_function(a_param) ⇒ Ok(a) ⇒ a) > (b_function(b_param) ⇒ Ok(b) ⇒ b)
532///
533/// This macro provides the same statements as [`assert_fn_ok_gt`](macro.assert_fn_ok_gt.html),
534/// except this macro's statements are only enabled in non-optimized
535/// builds by default. An optimized build will not execute this macro's
536/// statements unless `-C debug-assertions` is passed to the compiler.
537///
538/// This macro is useful for checks that are too expensive to be present
539/// in a release build but may be helpful during development.
540///
541/// The result of expanding this macro is always type checked.
542///
543/// An unchecked assertion allows a program in an inconsistent state to
544/// keep running, which might have unexpected consequences but does not
545/// introduce unsafety as long as this only happens in safe code. The
546/// performance cost of assertions, however, is not measurable in general.
547/// Replacing `assert*!` with `debug_assert*!` is thus only encouraged
548/// after thorough profiling, and more importantly, only in safe code!
549///
550/// This macro is intended to work in a similar way to
551/// [`::std::debug_assert`](https://doc.rust-lang.org/std/macro.debug_assert.html).
552///
553/// # Module macros
554///
555/// * [`assert_fn_ok_gt`](macro@crate::assert_fn_ok_gt)
556/// * [`assert_fn_ok_gt`](macro@crate::assert_fn_ok_gt)
557/// * [`debug_assert_fn_ok_gt`](macro@crate::debug_assert_fn_ok_gt)
558///
559#[macro_export]
560macro_rules! debug_assert_fn_ok_gt {
561    ($($arg:tt)*) => {
562        if $crate::cfg!(debug_assertions) {
563            $crate::assert_fn_ok_gt!($($arg)*);
564        }
565    };
566}