Skip to main content

assertables/assert_fn_ok/
assert_fn_ok_ne.rs

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