#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CompareOp {
GreaterOrEqual,
GreaterThan,
LessOrEqual,
LessThan,
Equal,
NotEqual,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct CompareExpr {
pub op: CompareOp,
pub threshold: i32,
}
impl CompareExpr {
pub fn parse(expr: &str) -> Option<Self> {
let (op, rest) = if let Some(rest) = expr.strip_prefix("GE") {
(CompareOp::GreaterOrEqual, rest)
} else if let Some(rest) = expr.strip_prefix("GT") {
(CompareOp::GreaterThan, rest)
} else if let Some(rest) = expr.strip_prefix("LE") {
(CompareOp::LessOrEqual, rest)
} else if let Some(rest) = expr.strip_prefix("LT") {
(CompareOp::LessThan, rest)
} else if let Some(rest) = expr.strip_prefix("NE") {
(CompareOp::NotEqual, rest)
} else if let Some(rest) = expr.strip_prefix("EQ") {
(CompareOp::Equal, rest)
} else {
return None;
};
Some(Self {
op,
threshold: rest.parse::<i32>().ok()?,
})
}
pub fn evaluate(self, value: i32) -> bool {
match self.op {
CompareOp::GreaterOrEqual => value >= self.threshold,
CompareOp::GreaterThan => value > self.threshold,
CompareOp::LessOrEqual => value <= self.threshold,
CompareOp::LessThan => value < self.threshold,
CompareOp::Equal => value == self.threshold,
CompareOp::NotEqual => value != self.threshold,
}
}
}
pub fn compare_expr(value: i32, expr: &str) -> bool {
if let Some(parsed) = CompareExpr::parse(expr) {
parsed.evaluate(value)
} else {
true
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn ge() {
assert!(compare_expr(2, "GE2"));
assert!(compare_expr(3, "GE2"));
assert!(!compare_expr(1, "GE2"));
}
#[test]
fn gt() {
assert!(compare_expr(3, "GT2"));
assert!(!compare_expr(2, "GT2"));
}
#[test]
fn le() {
assert!(compare_expr(2, "LE2"));
assert!(compare_expr(1, "LE2"));
assert!(!compare_expr(3, "LE2"));
}
#[test]
fn lt() {
assert!(compare_expr(1, "LT2"));
assert!(!compare_expr(2, "LT2"));
}
#[test]
fn eq() {
assert!(compare_expr(0, "EQ0"));
assert!(!compare_expr(1, "EQ0"));
}
#[test]
fn ne() {
assert!(compare_expr(1, "NE0"));
assert!(!compare_expr(0, "NE0"));
}
#[test]
fn unknown_is_permissive() {
assert!(compare_expr(42, "UNKNOWN"));
assert!(compare_expr(0, ""));
}
}