1
use tree_morph::prelude::*;
2
use uniplate::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

            
24
1
    let engine = EngineBuilder::new()
25
1
        .add_rule(
26
            // Same as macro expansion
27
4
            (|_, t, _| match t {
28
1
                Expr::A => Some(Expr::B),
29
3
                _ => None,
30
1
            }) as RuleFn<_, _>,
31
        )
32
1
        .add_rule_group(rule_fns![
33
3
            |_, t, _| match t {
34
1
                Expr::C => Some(Expr::D),
35
2
                _ => None,
36
3
            },
37
            rule_b_to_c,
38
        ])
39
1
        .build();
40

            
41
1
    let (result, _) = engine.morph(expr, ());
42

            
43
1
    assert_eq!(result, Expr::D);
44
1
}