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}