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
fn rule_b_to_c(_: &mut Commands<Expr, ()>, expr: &Expr, _: &()) -> Option<Expr> {
14
    if let Expr::B = expr {
15
        return Some(Expr::C);
16
    }
17
    None
18
}
19

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

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

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

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