1
use tree_morph::prelude::*;
2
use uniplate::derive::Uniplate;
3

            
4
#[derive(Debug, Clone, PartialEq, Eq, Uniplate)]
5
#[uniplate()]
6
enum Expr {
7
    A,
8
    B,
9
    C,
10
    D,
11
}
12

            
13
3
fn rule_b_to_c(_: &mut Commands<Expr, ()>, expr: &Expr, _: &()) -> Option<Expr> {
14
3
    if let Expr::B = expr {
15
1
        return Some(Expr::C);
16
2
    }
17
2
    None
18
3
}
19

            
20
#[test]
21
1
fn closure_rules() {
22
1
    let expr = Expr::A;
23
1

            
24
1
    let (result, _) = morph(
25
1
        vec![
26
1
            vec![
27
4
                (|_, t, _| match t {
28
1
                    Expr::A => Some(Expr::B),
29
3
                    _ => None,
30
1
                }) as RuleFn<_, _>, // Same as macro expansion
31
1
            ],
32
1
            rule_fns![
33
3
                |_, t, _| match t {
34
1
                    Expr::C => Some(Expr::D),
35
2
                    _ => None,
36
3
                },
37
1
                rule_b_to_c,
38
1
            ],
39
1
        ],
40
1
        select_first,
41
1
        expr,
42
1
        (),
43
1
    );
44
1

            
45
1
    assert_eq!(result, Expr::D);
46
1
}