use crate::filter::ComparisonOp;
#[derive(Debug, Clone, PartialEq)]
pub struct OperatorDef {
pub symbol: &'static str,
pub op: ComparisonOp,
pub needs_spaces: bool,
}
pub const OPERATORS: &[OperatorDef] = &[
OperatorDef {
symbol: "==",
op: ComparisonOp::Equal,
needs_spaces: false,
},
OperatorDef {
symbol: "!=",
op: ComparisonOp::NotEqual,
needs_spaces: false,
},
OperatorDef {
symbol: "<=",
op: ComparisonOp::LessThanOrEqual,
needs_spaces: false,
},
OperatorDef {
symbol: ">=",
op: ComparisonOp::GreaterThanOrEqual,
needs_spaces: false,
},
OperatorDef {
symbol: "^=",
op: ComparisonOp::StartsWith,
needs_spaces: false,
},
OperatorDef {
symbol: "$=",
op: ComparisonOp::EndsWith,
needs_spaces: false,
},
OperatorDef {
symbol: "*=",
op: ComparisonOp::Contains,
needs_spaces: false,
},
OperatorDef {
symbol: "<",
op: ComparisonOp::LessThan,
needs_spaces: true,
},
OperatorDef {
symbol: ">",
op: ComparisonOp::GreaterThan,
needs_spaces: true,
},
OperatorDef {
symbol: "~",
op: ComparisonOp::Matches,
needs_spaces: false,
},
];
pub const LOGICAL_OPERATORS: &[&str] = &["&&", "||", "!"];
pub fn parse_comparison_op(op_str: &str) -> ComparisonOp {
OPERATORS
.iter()
.find(|op| op.symbol == op_str)
.map(|op| op.op.clone())
.unwrap_or(ComparisonOp::Equal)
}
pub fn contains_filter_operators(input: &str) -> bool {
for op_def in OPERATORS {
if op_def.needs_spaces {
let spaced_op = format!(" {} ", op_def.symbol);
if input.contains(&spaced_op) || input.contains(op_def.symbol) {
return true;
}
} else if input.contains(op_def.symbol) {
return true;
}
}
for logical_op in LOGICAL_OPERATORS {
match *logical_op {
"&&" | "||" => {
if input.contains(logical_op) {
return true;
}
}
"!" => {
if input.starts_with("!") || input.contains(" ! ") {
return true;
}
}
_ => {
if input.contains(logical_op) {
return true;
}
}
}
}
false
}
pub fn get_all_operator_symbols() -> Vec<&'static str> {
OPERATORS.iter().map(|op| op.symbol).collect()
}
pub fn get_all_logical_symbols() -> Vec<&'static str> {
LOGICAL_OPERATORS.to_vec()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_comparison_op() {
assert_eq!(parse_comparison_op("=="), ComparisonOp::Equal);
assert_eq!(parse_comparison_op("!="), ComparisonOp::NotEqual);
assert_eq!(parse_comparison_op("<"), ComparisonOp::LessThan);
assert_eq!(parse_comparison_op("<="), ComparisonOp::LessThanOrEqual);
assert_eq!(parse_comparison_op(">"), ComparisonOp::GreaterThan);
assert_eq!(parse_comparison_op(">="), ComparisonOp::GreaterThanOrEqual);
assert_eq!(parse_comparison_op("*="), ComparisonOp::Contains);
assert_eq!(parse_comparison_op("^="), ComparisonOp::StartsWith);
assert_eq!(parse_comparison_op("$="), ComparisonOp::EndsWith);
assert_eq!(parse_comparison_op("~"), ComparisonOp::Matches);
assert_eq!(parse_comparison_op("unknown"), ComparisonOp::Equal);
}
#[test]
fn test_contains_filter_operators() {
assert!(contains_filter_operators("age > 25"));
assert!(contains_filter_operators("name == \"test\""));
assert!(contains_filter_operators("field != null"));
assert!(contains_filter_operators("score >= 90"));
assert!(contains_filter_operators("name *= something"));
assert!(contains_filter_operators("name ^= prefix"));
assert!(contains_filter_operators("path $= .txt"));
assert!(contains_filter_operators("text ~ pattern"));
assert!(contains_filter_operators("active && enabled"));
assert!(contains_filter_operators("status || fallback"));
assert!(contains_filter_operators("!active"));
assert!(!contains_filter_operators("simple_field"));
assert!(!contains_filter_operators("{template}"));
assert!(!contains_filter_operators("$variable"));
assert!(!contains_filter_operators("user.name"));
}
#[test]
fn test_get_operator_symbols() {
let symbols = get_all_operator_symbols();
assert!(symbols.contains(&"=="));
assert!(symbols.contains(&"*="));
assert!(symbols.contains(&">="));
assert_eq!(symbols.len(), OPERATORS.len());
}
#[test]
fn test_get_logical_symbols() {
let symbols = get_all_logical_symbols();
assert!(symbols.contains(&"&&"));
assert!(symbols.contains(&"||"));
assert!(symbols.contains(&"!"));
assert_eq!(symbols.len(), LOGICAL_OPERATORS.len());
}
}