1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
#[macro_use] extern crate lazy_static; extern crate unicode_normalization; use std::borrow::Borrow; use unicode_normalization::UnicodeNormalization; mod fuzz_search; pub use fuzz_search::fuzzy_search_score; use fuzz_search::fuzzy_search_score_no_norm; pub fn best_matches<T>(pattern: &str, items: Vec<T>, n: usize) -> impl Iterator<Item = T> where T: Borrow<str>, { best_matches_scores(pattern, items, n).map(|(name, _)| name).take(n) } pub fn best_matches_scores<T>( pattern: &str, items: Vec<T>, n: usize, ) -> impl Iterator<Item = (T, isize)> where T: Borrow<str>, { let pattern = pattern.nfc().collect::<String>(); let mut items_scores = items .into_iter() .map(|name| { let x = &name.borrow().nfc().collect::<String>(); (name, fuzzy_search_score_no_norm(&pattern, x)) }) .collect::<Vec<_>>(); items_scores.sort_by_key(|(_, x)| -x); items_scores.into_iter().take(n) } pub fn best_matches_scores_key<T, F, K>( pattern: &str, items: Vec<T>, f: F, n: usize, ) -> impl Iterator<Item = (T, isize)> where F: Fn(&T) -> K, K: Borrow<str>, { let pattern = pattern.nfc().collect::<String>(); let mut items_scores = items .into_iter() .map(|name| { let x = &f(&name).borrow().nfc().collect::<String>(); (name, fuzzy_search_score_no_norm(&pattern, x)) }) .collect::<Vec<_>>(); items_scores.sort_by_key(|(_, x)| -x); items_scores.into_iter().take(n) }