matches/
lib.rs

1#![no_std]
2
3/// Check if an expression matches a refutable pattern.
4///
5/// Syntax: `matches!(` *expression* `,` *pattern* `)`
6///
7/// Return a boolean, true if the expression matches the pattern, false otherwise.
8///
9/// # Examples
10///
11/// ```
12/// #[macro_use]
13/// extern crate matches;
14///
15/// pub enum Foo<T> {
16///     A,
17///     B(T),
18/// }
19///
20/// impl<T> Foo<T> {
21///     pub fn is_a(&self) -> bool {
22///         matches!(*self, Foo::A)
23///     }
24///
25///     pub fn is_b(&self) -> bool {
26///         matches!(*self, Foo::B(_))
27///     }
28/// }
29///
30/// # fn main() { }
31/// ```
32#[macro_export]
33macro_rules! matches {
34    ($expression:expr, $($pattern:tt)+) => {
35        match $expression {
36            $($pattern)+ => true,
37            _ => false
38        }
39    }
40}
41
42/// Assert that an expression matches a refutable pattern.
43///
44/// Syntax: `assert_matches!(` *expression* `,` *pattern* `)`
45///
46/// Panic with a message that shows the expression if it does not match the
47/// pattern.
48///
49/// # Examples
50///
51/// ```
52/// #[macro_use]
53/// extern crate matches;
54///
55/// fn main() {
56///     let data = [1, 2, 3];
57///     assert_matches!(data.get(1), Some(_));
58/// }
59/// ```
60#[macro_export]
61macro_rules! assert_matches {
62    ($expression:expr, $($pattern:tt)+) => {
63        match $expression {
64            $($pattern)+ => (),
65            ref e => panic!("assertion failed: `{:?}` does not match `{}`", e, stringify!($($pattern)+)),
66        }
67    }
68}
69
70/// Assert that an expression matches a refutable pattern using debug assertions.
71///
72/// Syntax: `debug_assert_matches!(` *expression* `,` *pattern* `)`
73///
74/// If debug assertions are enabled, panic with a message that shows the
75/// expression if it does not match the pattern.
76///
77/// When debug assertions are not enabled, this macro does nothing.
78///
79/// # Examples
80///
81/// ```
82/// #[macro_use]
83/// extern crate matches;
84///
85/// fn main() {
86///     let data = [1, 2, 3];
87///     debug_assert_matches!(data.get(1), Some(_));
88/// }
89/// ```
90#[macro_export]
91macro_rules! debug_assert_matches {
92    ($expression:expr, $($pattern:tt)+) => {
93        if cfg!(debug_assertions) {
94            match $expression {
95                $($pattern)+ => (),
96                ref e => panic!("assertion failed: `{:?}` does not match `{}`", e, stringify!($($pattern)+)),
97            }
98        }
99    }
100}
101
102#[test]
103fn matches_works() {
104    let foo = Some("-12");
105    assert!(matches!(foo, Some(bar) if
106        matches!(bar.as_bytes()[0], b'+' | b'-') &&
107        matches!(bar.as_bytes()[1], b'0'...b'9')
108    ));
109}
110
111#[test]
112fn assert_matches_works() {
113    let foo = Some("-12");
114    assert_matches!(foo, Some(bar) if
115        matches!(bar.as_bytes()[0], b'+' | b'-') &&
116        matches!(bar.as_bytes()[1], b'0'...b'9')
117    );
118}
119
120#[test]
121#[should_panic(expected = "assertion failed: `Some(\"-AB\")` does not match ")]
122fn assert_matches_panics() {
123    let foo = Some("-AB");
124    assert_matches!(foo, Some(bar) if
125        matches!(bar.as_bytes()[0], b'+' | b'-') &&
126        matches!(bar.as_bytes()[1], b'0'...b'9')
127    );
128}