1pub fn fuzzy_search<'a, T>(array: &'a [T], target: &str, tolerance: usize, extract: fn(&T) -> &str) -> Vec<&'a T> {
2 let mut results = Vec::with_capacity(array.len());
3
4 for item in array {
5 let item_str = extract(item);
6 if fuzzy_match(item_str, target, tolerance) {
7 results.push(item);
8 }
9 }
10
11 results
12}
13
14pub fn fuzzy_match(s1: &str, s2: &str, tolerance: usize) -> bool {
15 let len_diff = s1.len().abs_diff(s2.len());
16 if len_diff > tolerance {
17 return false;
18 }
19
20 let mut errors = len_diff;
21 let mut s1_iter = s1.chars();
22 let mut s2_iter = s2.chars();
23
24 while let (Some(c1), Some(c2)) = (s1_iter.next(), s2_iter.next()) {
25 if c1 != c2 {
26 errors += 1;
27 if errors > tolerance {
28 return false;
29 }
30 }
31 }
32
33 errors <= tolerance
34}