iflet/
lib.rs

1#[macro_export]
2macro_rules! if_chain {
3    ( [ let $l:pat $( if $c:expr ),* => $r:expr ] $b:block ) => {{
4        #[allow(unreachable_patterns)]
5        match $r {
6            $l $(if $c),* => $b
7            _ => {}
8        }
9    }};
10
11    ([ let $l:pat $( if $c:expr ),* => $r:expr ] $b1:block else $b2:block ) => {{
12        #[allow(unreachable_patterns)]
13        match $r {
14            $l $( if $c ),* => $b1
15            _ => $b2
16        }
17    }};
18
19    ([ let $l:pat $( if $c:expr ),* => $r:expr $(, let $ll:pat $( if $cc:expr ),* => $rr:expr )+ ] $b:block ) => {{
20        #[allow(unreachable_patterns)]
21        match $r {
22            $l $( if $c ),* => if_chain!([$( let $ll $( if $cc ),* => $rr ),+] $b),
23            _ => {}
24        }
25    }};
26
27    ([ let $l:pat $( if $c:expr ),* => $r:expr $(, let $ll:pat $( if $cc:expr ),* => $rr:expr )+ ] $b1:block else $b2:block) => {{
28        #[allow(unreachable_patterns)]
29        match $r {
30            $l $(if $c ),* => if_chain!([$( let $ll $( if $cc ),* => $rr ),+] $b1 else $b2),
31            _ => $b2
32        }
33    }};
34}
35
36//
37// no else, no guard
38//
39
40#[test]
41fn match_without_else_succeeds() {
42    let x = Some(3);
43
44    if_chain!([let Some(y) => x] {
45        assert_eq!(y, 3);
46        return;
47    });
48
49    panic!("match failed when success was expected!");
50}
51
52#[test]
53fn match_without_else_fails() {
54    let x: Option<()> = None;
55
56    if_chain!([let Some(_) => x] {
57        panic!("match succeeded when failure was expected!");
58    });
59}
60
61#[test]
62fn multi_match_without_else_succeeds() {
63    let x = Some(3);
64    let y: Result<&str, ()> = Ok("foo");
65    let z = (false, -117);
66
67    if_chain!([let Some(a) => x,
68               let Ok(b) => y,
69               let (c, d) => z] {
70        assert_eq!(a, 3);
71        assert_eq!(b, "foo");
72        assert_eq!(c, false);
73        assert_eq!(d, -117);
74        return;
75    });
76
77    panic!("match failed when success was expected");
78}
79
80#[test]
81fn multi_match_without_else_fails() {
82    let x: Option<()> = None;
83    let y: Result<&str, ()> = Ok("foo");
84    let z = (false, -117);
85
86    if_chain!([let Some(_) => x,
87               let Ok(_) => y,
88               let (_, _) => z] {
89        panic!("match succeeded when failure was expected!");
90    });
91}
92
93//
94// with else, no guard
95//
96
97#[test]
98fn match_with_else_succeeds() {
99    let x = Some(3);
100
101    if_chain!([let Some(y) => x] {
102        assert_eq!(y, 3);
103    } else {
104        panic!("match failed when success was expected!");
105    });
106}
107
108#[test]
109fn match_with_else_fails() {
110    let x: Option<()> = None;
111
112    if_chain!([let Some(_) => x] {
113        panic!("match succeeded when failure was expected!");
114    } else {
115        assert!(true);
116    });
117}
118
119#[test]
120fn multi_match_with_else_succeeds() {
121    let x = Some(3);
122    let y: Result<&str, ()> = Ok("foo");
123    let z = (false, -117);
124
125    if_chain!([let Some(a) => x,
126               let Ok(b) => y,
127               let (c, d) => z] {
128        assert_eq!(a, 3);
129        assert_eq!(b, "foo");
130        assert_eq!(c, false);
131        assert_eq!(d, -117);
132        return;
133    } else {
134        panic!("match failed when success was expected");
135    });
136}
137
138#[test]
139fn multi_match_with_else_fails() {
140    let x = Some(3);
141    let y: Result<&str, ()> = Err(());
142    let z = (false, -117);
143
144    if_chain!([let Some(_) => x,
145               let Ok(_) => y,
146               let (_, _) => z] {
147        panic!("match succeeded when failure was expected");
148    } else {
149        assert!(true);
150    });
151}
152
153//
154// no else, with guard
155//
156
157#[test]
158fn match_without_else_with_guard_succeeds() {
159    let x = Some(3);
160
161    if_chain!([let Some(y) if y > 2 => x] {
162        assert_eq!(y, 3);
163        return;
164    });
165
166    panic!("match failed when success was expected!");
167}
168
169#[test]
170fn match_without_else_with_guard_fails() {
171    let x: Option<i8> = None;
172
173    if_chain!([let Some(_y) if _y > 2 => x] {
174        panic!("match succeeded when failure was expected!");
175    });
176}
177
178#[test]
179fn match_without_else_with_guard_fails_from_guard() {
180    let x = Some(3);
181
182    if_chain!([let Some(_y) if _y > 4 => x] {
183        panic!("match succeeded when failure was expected!");
184    });
185}
186
187#[test]
188fn multi_match_without_else_with_guard_succeeds() {
189    let x = Some(3);
190    let y: Result<&str, ()> = Ok("foo");
191    let z = (false, -117);
192
193    if_chain!([let Some(a) if a > 2 => x,
194               let Ok(b) => y,
195               let (c, d) if !c => z] {
196        assert_eq!(a, 3);
197        assert_eq!(b, "foo");
198        assert_eq!(c, false);
199        assert_eq!(d, -117);
200        return;
201    });
202
203    panic!("match failed when success was expected");
204}
205
206#[test]
207fn multi_match_without_else_with_guard_fails() {
208    let x: Option<()> = None;
209    let y: Result<i8, ()> = Ok(3);
210    let z = (false, -117);
211
212    if_chain!([let Some(_) => x,
213               let Ok(_b) if _b > 2 => y,
214               let (_, _) => z] {
215        panic!("match succeeded when failure was expected!");
216    });
217}
218
219#[test]
220fn multi_match_without_else_with_guard_fails_from_guard() {
221    let x = Some(3);
222    let y: Result<&str, ()> = Ok("foo");
223    let z = (false, -117);
224
225    if_chain!([let Some(_a) => x,
226               let Ok(_b) => y,
227               let (_c, _) if _c => z] {
228        panic!("match succeeded when failure was expected!");
229    });
230}
231
232//
233// with else, with guard
234//
235
236#[test]
237fn match_with_else_with_guard_succeeds() {
238    let x = Some(3);
239
240    if_chain!([let Some(y) if y > 2 => x] {
241        assert_eq!(y, 3);
242    } else {
243        panic!("match failed when success was expected!");
244    });
245}
246
247#[test]
248fn match_with_else_with_guard_fails() {
249    let x: Option<bool> = None;
250
251    if_chain!([let Some(_y) if _y => x] {
252        panic!("match succeeded when failure was expected!");
253    } else {
254        assert!(true);
255    });
256}
257
258#[test]
259fn match_with_else_with_guard_fails_from_guard() {
260    let x = Some(false);
261
262    if_chain!([let Some(_y) if _y => x] {
263        panic!("match succeeded when failure was expected!");
264    } else {
265        assert!(true);
266    });
267}
268
269#[test]
270fn multi_match_with_else_with_guard_succeeds() {
271    let x = Some(3);
272    let y: Result<&str, ()> = Ok("foo");
273    let z = (false, -117);
274
275    if_chain!([let Some(a) => x,
276               let Ok(b) if !b.is_empty() => y,
277               let (c, d) if d < 0 => z] {
278        assert_eq!(a, 3);
279        assert_eq!(b, "foo");
280        assert_eq!(c, false);
281        assert_eq!(d, -117);
282        return;
283    } else {
284        panic!("match failed when success was expected");
285    });
286}
287
288#[test]
289fn multi_match_with_else_with_guard_fails() {
290    let x = Some(3);
291    let y: Result<&str, ()> = Err(());
292    let z = (false, -117);
293
294    if_chain!([let Some(_a) if _a > 2 => x,
295               let Ok(_) => y,
296               let (_, _) => z] {
297        panic!("match succeeded when failure was expected");
298    } else {
299        assert!(true);
300    });
301}
302
303#[test]
304fn multi_match_with_else_with_guard_fails_from_guard() {
305    let x = Some(3);
306    let y: Result<&str, ()> = Err(());
307    let z = (false, -117);
308
309    if_chain!([let Some(_a) if _a > 2 => x,
310               let Ok(_) => y,
311               let (_, _) => z] {
312        panic!("match succeeded when failure was expected");
313    } else {
314        assert!(true);
315    });
316}