Skip to content

Commit 2f16e78

Browse files
committed
Rustify the fuzzy search
The previous version used a bunch of manual string splitting and recursion and bad decisions. Recursion - To my knowledge, Rust doesn't support tail call optimization, so recursion can eventually blow the stack on long strings. rust-lang/rust#217 String Splitting - Given that Rust strings are UTF8, there's a non-zero chance that the algorithm may split on a non-character boundary if the code isn't careful. Development while creating the split was problematic at best and resulted in lots of issues involving the boundary. Bad decisions - I originally wrote the code in a way that bent Rust to my will rather than using what Rust provided.
1 parent 83c561a commit 2f16e78

File tree

1 file changed

+14
-42
lines changed

1 file changed

+14
-42
lines changed

fuzzy_search/src/lib.rs

Lines changed: 14 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -26,54 +26,26 @@
2626
/// assert_eq!(fuzzy_search_match("abc", "abcdefg"), true);
2727
/// ```
2828
pub fn fuzzy_search_match(search_string: &str, reference_string: &str) -> bool {
29-
recursive_fuzzy_search(search_string, reference_string)
29+
fuzzy_search(reference_string, search_string)
3030
}
3131

32-
fn recursive_fuzzy_search(search_string: &str, reference_string: &str) -> bool {
33-
let search_len: usize = search_string.len();
34-
let reference_len: usize = reference_string.len();
35-
36-
if search_string == "" {
37-
return true;
38-
}
39-
40-
if reference_string == "" {
41-
return false;
42-
}
43-
44-
// Search strings longer than the reference strings are not valid
45-
if reference_len < search_len {
46-
return false;
47-
}
48-
49-
for (search_index, search_value) in search_string.char_indices() {
50-
// Case where all chars in search string are found
51-
if search_index == search_len {
52-
return true;
53-
}
54-
55-
for (reference_index, reference_value) in reference_string.char_indices() {
56-
if search_value == reference_value {
57-
let (_, rhs_reference_substring) = reference_string.split_at(find_next_char_boundary(reference_string, reference_index));
58-
let (_, rhs_search_substring) = search_string.split_at(find_next_char_boundary(search_string, search_index));
59-
return recursive_fuzzy_search(rhs_search_substring, rhs_reference_substring);
32+
fn fuzzy_search(reference_string: &str, search_string: &str) -> bool {
33+
let mut search_iterator = search_string.chars();
34+
let mut search = search_iterator.next();
35+
36+
for ref_char in reference_string.chars() {
37+
match search {
38+
Some(search_char) => {
39+
if search_char == ref_char {
40+
search = search_iterator.next();
41+
continue;
42+
}
6043
}
61-
}
62-
63-
return false;
64-
}
65-
66-
false
67-
}
68-
69-
fn find_next_char_boundary(string: &str, index: usize) -> usize {
70-
for offset in 1..string.len() + 1 {
71-
if string.is_char_boundary(index + offset) {
72-
return index + offset;
44+
None => return true
7345
}
7446
}
7547

76-
index
48+
search == None
7749
}
7850

7951

0 commit comments

Comments
 (0)