rustcane/
lib.rs

1/// Executes a sequence of pattern matching statements in order. If any match fails, the result is given as an `else`
2/// expression. Otherwise the result is given as the `lift` expression.
3#[macro_export]
4macro_rules! lets {
5    // Base case for pattern matching statements.
6    (
7        let $expect:pat = $result:expr;
8        else $failure:expr;
9        lift $success:expr;
10    ) => {
11        match $result {
12            $expect => $success,
13            _ => $failure,
14        }
15    };
16
17    // Implicit else.
18    (
19        $(let $expect:pat = $result:expr;)+
20        lift $success:expr;
21    ) => {
22        lets! {
23            $(let $expect = $result;)*
24            else ();
25            lift $success;
26        }
27    };
28
29    // Implicit lift.
30    (
31        $(let $expect:pat = $result:expr;)+
32        else $failure:expr;
33    ) => {
34        lets! {
35            $(let $expect = $result;)*
36            else $failure;
37            lift ();
38        }
39    };
40
41    // Implicit else and lift.
42    (
43        $(let $expect:pat = $result:expr;)+
44    ) => {
45        lets! {
46            $(let $expect = $result;)*
47            else ();
48            lift ();
49        }
50    };
51
52    // Main case: multiple let statemens in a row.
53    (
54        let $expect_first:pat = $result_first:expr;
55        $(let $expect_next:pat = $result_next:expr;)+
56        else $failure:expr;
57        lift $success:expr;
58    ) => {
59        match $result_first {
60            $expect_first => lets! {
61                $(let $expect_next = $result_next;)*
62                else $failure;
63                lift $success;
64            },
65            _ => $failure,
66        }
67    };
68}