pub(crate) const CASE_PREFIXABLE: &[&str] = &[
"eq",
"ne",
"gt",
"ge",
"lt",
"le",
"like",
"notlike",
"match",
"notmatch",
"contains",
"notcontains",
"in",
"notin",
"replace",
"split",
];
pub(crate) fn is_named_operator_word(core: &str, base: &[&str]) -> bool {
if base.iter().any(|n| n.eq_ignore_ascii_case(core)) {
return true;
}
match core.as_bytes().first() {
Some(b'c' | b'C' | b'i' | b'I') => CASE_PREFIXABLE
.iter()
.any(|n| n.eq_ignore_ascii_case(&core[1..])),
_ => false,
}
}
#[cfg(test)]
mod tests {
use super::*;
const BASE: &[&str] = &["eq", "in", "contains", "and", "f", "is"];
#[test]
fn full_name_wins_before_prefix_stripping() {
assert!(is_named_operator_word("contains", BASE));
assert!(is_named_operator_word("in", BASE));
assert!(is_named_operator_word("Is", BASE));
}
#[test]
fn case_prefix_applies_only_to_the_prefixable_set() {
assert!(is_named_operator_word("cin", BASE));
assert!(is_named_operator_word("ieq", BASE));
assert!(is_named_operator_word("CnotIn", BASE));
assert!(!is_named_operator_word("cand", BASE));
assert!(!is_named_operator_word("cf", BASE));
assert!(!is_named_operator_word("cis", BASE));
}
}