use std::iter;
use nom::InputIter;
use rand::{distributions::Alphanumeric, thread_rng, Rng};
pub fn rand_str() -> String {
let mut rng = thread_rng();
let chars: String = iter::repeat(())
.map(|()| rng.sample(Alphanumeric))
.map(char::from)
.take(15)
.collect();
chars
}
pub fn fuzzy_search(exp: &str, value: &str) -> bool {
if exp.is_empty() {
return true;
}
let mut exp_chars = exp.chars();
let mut match_curr_char = exp_chars.next();
let mut wildcard_state = 0;
for letter in value.iter_elements() {
if match_curr_char.is_some() && match_curr_char.unwrap() == '*' {
wildcard_state = u16::MAX;
match_curr_char = exp_chars.next();
} else if match_curr_char.is_some() && match_curr_char.unwrap() == '?' {
wildcard_state = 1;
match_curr_char = exp_chars.next();
}
if match_curr_char.is_some() && match_curr_char.unwrap() == letter {
wildcard_state = 0;
match_curr_char = exp_chars.next();
} else if wildcard_state > 0 {
wildcard_state -= 1;
} else {
return false;
}
}
if wildcard_state == 1 {
return false;
}
if match_curr_char.is_some() && match_curr_char.unwrap() != '*' {
return false;
}
exp_chars.next().is_none()
}
#[test]
fn test_fuzzy_search() {
assert!(fuzzy_search("*.info", "mrxzx.info"));
assert!(fuzzy_search("L?uYuK?n", "LiuYuKun"));
assert!(!fuzzy_search("*.com", "mrxzx.info"));
assert!(!fuzzy_search("?.com", "baidu.com"));
assert!(!fuzzy_search("dorea-server", "dorea-ser"));
assert!(!fuzzy_search("dorea-ser", "dorea-server"));
assert!(!fuzzy_search("dorea?", "dorea"));
assert!(fuzzy_search("dorea*", "dorea"));
}