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}