manabrew_engine/parsing/
compare.rs1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub enum CompareOp {
11 GreaterOrEqual,
12 GreaterThan,
13 LessOrEqual,
14 LessThan,
15 Equal,
16 NotEqual,
17}
18
19#[derive(Debug, Clone, Copy, PartialEq, Eq)]
20pub struct CompareExpr {
21 pub op: CompareOp,
22 pub threshold: i32,
23}
24
25impl CompareExpr {
26 pub fn parse(expr: &str) -> Option<Self> {
27 let (op, rest) = if let Some(rest) = expr.strip_prefix("GE") {
28 (CompareOp::GreaterOrEqual, rest)
29 } else if let Some(rest) = expr.strip_prefix("GT") {
30 (CompareOp::GreaterThan, rest)
31 } else if let Some(rest) = expr.strip_prefix("LE") {
32 (CompareOp::LessOrEqual, rest)
33 } else if let Some(rest) = expr.strip_prefix("LT") {
34 (CompareOp::LessThan, rest)
35 } else if let Some(rest) = expr.strip_prefix("NE") {
36 (CompareOp::NotEqual, rest)
37 } else if let Some(rest) = expr.strip_prefix("EQ") {
38 (CompareOp::Equal, rest)
39 } else {
40 return None;
41 };
42 Some(Self {
43 op,
44 threshold: rest.parse::<i32>().ok()?,
45 })
46 }
47
48 pub fn evaluate(self, value: i32) -> bool {
49 match self.op {
50 CompareOp::GreaterOrEqual => value >= self.threshold,
51 CompareOp::GreaterThan => value > self.threshold,
52 CompareOp::LessOrEqual => value <= self.threshold,
53 CompareOp::LessThan => value < self.threshold,
54 CompareOp::Equal => value == self.threshold,
55 CompareOp::NotEqual => value != self.threshold,
56 }
57 }
58}
59
60pub fn compare_expr(value: i32, expr: &str) -> bool {
83 if let Some(parsed) = CompareExpr::parse(expr) {
84 parsed.evaluate(value)
85 } else {
86 true
88 }
89}
90
91#[cfg(test)]
92mod tests {
93 use super::*;
94
95 #[test]
96 fn ge() {
97 assert!(compare_expr(2, "GE2"));
98 assert!(compare_expr(3, "GE2"));
99 assert!(!compare_expr(1, "GE2"));
100 }
101
102 #[test]
103 fn gt() {
104 assert!(compare_expr(3, "GT2"));
105 assert!(!compare_expr(2, "GT2"));
106 }
107
108 #[test]
109 fn le() {
110 assert!(compare_expr(2, "LE2"));
111 assert!(compare_expr(1, "LE2"));
112 assert!(!compare_expr(3, "LE2"));
113 }
114
115 #[test]
116 fn lt() {
117 assert!(compare_expr(1, "LT2"));
118 assert!(!compare_expr(2, "LT2"));
119 }
120
121 #[test]
122 fn eq() {
123 assert!(compare_expr(0, "EQ0"));
124 assert!(!compare_expr(1, "EQ0"));
125 }
126
127 #[test]
128 fn ne() {
129 assert!(compare_expr(1, "NE0"));
130 assert!(!compare_expr(0, "NE0"));
131 }
132
133 #[test]
134 fn unknown_is_permissive() {
135 assert!(compare_expr(42, "UNKNOWN"));
136 assert!(compare_expr(0, ""));
137 }
138}