extract/
lib.rs

1/// Returns the extracted value from the provided patterns.
2///
3/// Like a `match` expression, a pattern can be optionally followed by an `if` guard that has access
4/// to names bound by the pattern.
5///
6/// ```
7/// # use extract::extract;
8/// let array = [1, 2, 3];
9/// let first = extract!(array, [el, ..] => el);
10/// assert_eq!(first, Some(1));
11/// ```
12#[macro_export]
13macro_rules! extract {
14    ($expression:expr, $(
15        $(|)? $( $pattern:pat_param )|+ $( if $guard: expr )? => $output:expr
16    ),+ $(,)?) => {
17        match $expression {
18            $($( $pattern )|+ $( if $guard )? => Some($output),)+
19            _ => None
20        }
21    }
22}
23
24#[cfg(test)]
25mod test {
26    #[test]
27    fn array() {
28        let array = &[1, 2, 3, 4, 5][..];
29
30        let first = extract!(*array, [el, ..] => el);
31        assert_eq!(first, Some(1));
32
33        let second = extract!(*array, [_, el, ..] => el);
34        assert_eq!(second, Some(2));
35
36        let third = extract!(*array, [_, _, el, ..] => el);
37        assert_eq!(third, Some(3));
38
39        let multi_pattern = extract!(*array,
40            [el] => el,
41            [_, el] => el,
42            [_, _, el] => el,
43            [_, _, _, el] => el,
44            [_, _, _, _, el] => el,
45            [_, _, _, _, _, el] => el,
46        );
47        assert_eq!(multi_pattern, Some(5));
48
49        let sixth = extract!(*array, [_, _, _, _, _, el] => el);
50        assert_eq!(sixth, None);
51    }
52}