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