hex_patch/fuzzer/
fuzzer.rspub fn fuzzy_search_cloned<T>(key: &str, entries: &[T]) -> Vec<T>
where
T: AsRef<str> + Clone,
{
let mut ret = entries.to_vec();
fuzzy_search_in_place(key, &mut ret);
ret
}
pub fn fuzzy_search_in_place<T>(key: &str, entries: &mut [T])
where
T: AsRef<str> + Clone,
{
entries.sort_by_cached_key(|source| -score(source.as_ref(), key));
}
fn score(source: &str, key: &str) -> isize {
let mut score = 0;
let char_found_bonus = 10;
let key_char_not_found_penalty = -5;
let self_char_not_found_penalty = -1;
let mut key_chars = key.chars();
let self_chars = source.chars();
let mut current_key_char = key_chars.next();
for self_char in self_chars {
if let Some(key_char) = current_key_char {
if self_char == key_char {
score += char_found_bonus;
current_key_char = key_chars.next();
} else {
score += self_char_not_found_penalty;
}
} else {
break;
}
}
for _ in key_chars {
score += key_char_not_found_penalty;
}
score
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_fuzzy_search() {
let entries = vec!["abc", "def", "ghi", "jkl"];
let result = fuzzy_search_cloned("d", &entries);
assert_eq!(result, vec!["def", "abc", "ghi", "jkl"]);
}
}