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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
pub mod interpreter;
mod parser;

use parser::comparison::Comparison;
use parser::relation::Relation;

#[derive(Debug)]
pub enum Node {
    And(Box<Expression>, Box<Expression>),
    Or(Box<Expression>, Box<Expression>),
    Not(Box<Expression>),
    Equal(String, String),
    EqualCI(String, String),
    Greater(String, String),
    Less(String, String),
    Wildcard(String, String),
    Regex(String, String),
    Any(String, Vec<String>),
    Null(String),
}

#[derive(Debug)]
pub struct Expression {
    pub node: Node,
}

impl From<Comparison> for Expression {
    fn from(c: Comparison) -> Self {
        match c {
            Comparison::IsEqual(c) => Self {
                node: Node::Equal(c.left.0, c.right.0),
            },
            Comparison::IsEqualCI(c) => Self {
                node: Node::EqualCI(c.left.0, c.right.0),
            },
            Comparison::IsGreater(c) => Self {
                node: Node::Greater(c.left.0, c.right.0),
            },
            Comparison::IsLess(c) => Self {
                node: Node::Less(c.left.0, c.right.0),
            },
            Comparison::IsWildcard(c) => Self {
                node: Node::Wildcard(c.left.0, c.right.0),
            },
            Comparison::IsRegex(c) => Self {
                node: Node::Regex(c.left.0, c.right.0),
            },
            Comparison::IsAny(c) => Self {
                node: Node::Any(c.left.0, c.right.0),
            },
            Comparison::IsNull(c) => Self {
                node: Node::Null(c.0 .0),
            },
        }
    }
}

impl From<Box<Relation>> for Expression {
    fn from(relation: Box<Relation>) -> Self {
        match *relation {
            Relation::C(c) => c.into(),
            Relation::RAR { left, right } => Self {
                node: Node::And(Box::new(left.into()), Box::new(right.into())),
            },
            Relation::RAC { left, right } => Self {
                node: Node::And(Box::new(left.into()), Box::new(right.into())),
            },
            Relation::CAR { left, right } => Self {
                node: Node::And(Box::new(left.into()), Box::new(right.into())),
            },
            Relation::CAC { left, right } => Self {
                node: Node::And(Box::new(left.into()), Box::new(right.into())),
            },
            Relation::ROR { left, right } => Self {
                node: Node::Or(Box::new(left.into()), Box::new(right.into())),
            },
            Relation::ROC { left, right } => Self {
                node: Node::Or(Box::new(left.into()), Box::new(right.into())),
            },
            Relation::COR { left, right } => Self {
                node: Node::Or(Box::new(left.into()), Box::new(right.into())),
            },
            Relation::COC { left, right } => Self {
                node: Node::Or(Box::new(left.into()), Box::new(right.into())),
            },
            Relation::NR(r) => Self {
                node: Node::Not(Box::new(r.into())),
            },
            Relation::NC(c) => Self {
                node: Node::Not(Box::new(c.into())),
            },
        }
    }
}

impl Expression {
    pub fn try_from_str(s: &str) -> Result<Self, String> {
        Ok(parser::relation::relation(s)
            .map_err(|err| err.to_string())?
            .1
            .into())
    }
}