1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#[macro_export]
macro_rules! match_or {
    ([$e:expr] $($arm_pat:pat => $arm_body:expr),*; $or:expr) => {
        match $e {
            $( $arm_pat => $arm_body, )*
            _ => $or,
        }
    };
}

#[macro_export]
macro_rules! expect {
    ([$e:expr] $arm_pat:pat => $arm_body:expr) => {
        match_or!([$e] $arm_pat => $arm_body;
            panic!(concat!("expected ", stringify!($arm_pat))))
    };
    ([$e:expr] $($arm_pat:pat => $arm_body:expr),*) => {
        match_or!([$e] $($arm_pat => $arm_body),*;
            panic!(concat!("expected one of: ",
                           stringify!($($arm_pat),*))))
    };
}

#[macro_export]
macro_rules! unpack {
    ([$e:expr] $enum_:ident :: $variant:ident ( $($arg:ident),* )) => {
        let ($($arg,)*) = expect!([$e] $enum_::$variant($($arg),*) => ($($arg,)*));
    };
}

#[macro_export]
macro_rules! matches {
    ([$e:expr] $($pat:pat),*) => {
        match $e {
            $( $pat => true, )*
            _ => false,
        }
    };
}