radix_rust/
macros.rs

1/// Attempts to be a replacement for `assert!(matches!(...))` but with better error messages,
2/// and allowing further code on success.
3///
4/// Matches the [`assert_eq!`] syntax for error messages.
5///
6/// ```rust
7/// # use radix_rust::assert_matches;
8/// let x = Some(42);
9/// assert_matches!(x, Some(_));
10/// ```
11///
12/// ```rust
13/// # use radix_rust::assert_matches;
14/// # let x = Some(42);
15/// assert_matches!(x, Some(x) => { assert_eq!(x, 42); });
16/// ```
17///
18/// ```rust,should_panic
19/// # use radix_rust::assert_matches;
20/// # let x = Some(42);
21/// assert_matches!(x, None, "Expected None, got {:?}", x);
22/// ```
23///
24/// ```rust,should_panic
25/// # use radix_rust::assert_matches;
26/// # let x = Some(42);
27/// assert_matches!(x, Some(x) => { assert_eq!(x, 41); }, "Expected Some(41), got {:?}", x);
28/// ```
29///
30/// ## Alternatives
31/// We can't use the std [assert_matches!](https://github.com/rust-lang/rust/issues/82775) macro,
32/// as it looks like it is doomed to be stuck unstabilized for the foreseeable future.
33///
34/// This takes some inspiration regarding the `=> {}` syntax from the
35/// [assert_matches](https://docs.rs/assert_matches/1.5.0/assert_matches/macro.assert_matches.html)
36/// crate but the code had bugs with trailing commas and its error messages weren't ideal.
37#[macro_export]
38macro_rules! assert_matches {
39    ($expression:expr, $pattern:pat $(if $condition:expr)? $(,)?) => {
40        match $expression {
41            $pattern $(if $condition)? => (),
42            ref expression => panic!(
43                "assertion `left matches right` failed\n  left: {:?}\n right: {}",
44                expression,
45                stringify!($pattern $(if $condition)?),
46            )
47        }
48    };
49    ($expression:expr, $pattern:pat $(if $condition:expr)? => $code:expr $(,)?) => {
50        match $expression {
51            $pattern $(if $condition)? => $code,
52            ref expression => panic!(
53                "assertion `left matches right` failed\n  left: {:?}\n right: {}",
54                expression,
55                stringify!($pattern $(if $condition)?),
56            )
57        }
58    };
59    ($expression:expr, $pattern:pat $(if $condition:expr)?, $($arg:tt)+) => {
60        match $expression {
61            $pattern $(if $condition)? => (),
62            ref expression => panic!(
63                "assertion `left matches right` failed: {}\n  left: {:?}\n right: {}",
64                format_args!($($arg)+),
65                expression,
66                stringify!($pattern $(if $condition)?),
67            )
68        }
69    };
70    ($expression:expr, $pattern:pat $(if $condition:expr)? => $code:expr, $($arg:tt)+) => {
71        match $expression {
72            $pattern $(if $condition)? => $code,
73            ref expression => panic!(
74                "assertion `left matches right` failed: {}\n  left: {:?}\n right: {}",
75                format_args!($($arg)+),
76                expression,
77                stringify!($pattern $(if $condition)?),
78            )
79        }
80    };
81}