use std::fmt;
use radix_trie::TrieCommon;
type MatchesTrie = radix_trie::Trie<String, ()>;
pub struct Matches {
matches: MatchesTrie,
}
impl Matches {
pub fn new(mut key_prefixes: Vec<String>) -> Matches {
const EMPTY: () = ();
let matches: MatchesTrie = key_prefixes.drain(..).map(|x| (x, EMPTY)).collect();
Matches { matches }
}
pub fn key_matches(&self, key: &str) -> bool {
if self.matches.is_empty() {
true
} else {
self.matches.get_ancestor(key).is_some()
}
}
}
impl fmt::Debug for Matches {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_set().entries(self.matches.keys()).finish()
}
}
#[cfg(test)]
mod test {
use super::Matches;
use std::result::Result;
type TestResult = Result<(), Box<dyn std::error::Error>>;
#[test]
fn matches_assumption_works() -> TestResult {
let prefix = vec![
"abc.def".to_string(),
"abc.def.ghi".to_string(),
"cde.def.ghi".to_string(),
];
let matches = Matches::new(prefix);
assert!(matches.key_matches("abc.def"));
assert!(matches.key_matches("abc.def.ghi"));
assert!(matches.key_matches("abc.def.ghi.bar.bar.bar"));
assert!(!matches.key_matches("abcdef"));
assert!(!matches.key_matches(""));
assert!(!matches.key_matches("cde"));
assert!(!matches.key_matches("abc.del"));
assert!(!matches.key_matches("cde.def.gh"));
Ok(())
}
#[test]
fn empty_matches_work() -> TestResult {
let prefix = Vec::<String>::new();
let matches = Matches::new(prefix);
assert!(matches.key_matches("abc.def"));
assert!(matches.key_matches("cde"));
assert!(matches.key_matches("abc.del"));
assert!(matches.key_matches("cde.def.gh"));
Ok(())
}
}