fuzz_search/
lib.rs

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