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