Correct-ish implementation with binary search
This commit is contained in:
parent
0b697f5484
commit
aca4628594
@ -192,26 +192,42 @@ impl ArtistSelection {
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: think about converting punctuation characters to some common character.
|
||||
fn normalize_search_string(search: &str, lowercase: bool) -> String {
|
||||
let normalized = if lowercase {
|
||||
search.to_lowercase()
|
||||
} else {
|
||||
search.to_owned()
|
||||
};
|
||||
|
||||
// Unlikely that this covers all possible strings, but it should at least cover strings
|
||||
// relevant for music (at least in English). The list of characters handled is based on
|
||||
// https://wiki.musicbrainz.org/User:Yurim/Punctuation_and_Special_Characters.
|
||||
normalized
|
||||
.replace("‐", "-") // U+2010 hyphen
|
||||
.replace("‒", "-") // U+2012 figure dash
|
||||
.replace("–", "-") // U+2013 en dash
|
||||
.replace("—", "-") // U+2014 em dash
|
||||
.replace("―", "-") // U+2015 horizontal bar
|
||||
.replace("‘", "'") // U+2018
|
||||
.replace("’", "'") // U+2019
|
||||
.replace("“", "\"") // U+201C
|
||||
.replace("”", "\"") // U+201D
|
||||
.replace("…", "...") // U+2026
|
||||
.replace("−", "-") // U+2212 minus sign
|
||||
}
|
||||
|
||||
fn incremental_search(&mut self, artists: &[Artist], artist_name: &str) {
|
||||
if let Some(index) = self.state.list.selected() {
|
||||
let case_sensitive = artist_name
|
||||
.chars()
|
||||
.any(|ch| !(ch.is_lowercase() || ch.is_whitespace() || ch.is_ascii_punctuation()));
|
||||
.any(|ch| ch.is_alphabetic() && ch.is_uppercase());
|
||||
let search_name = Self::normalize_search_string(artist_name, !case_sensitive);
|
||||
let slice = &artists[index..];
|
||||
|
||||
let result = if case_sensitive {
|
||||
slice.binary_search_by(|probe| probe.get_sort_key().name.as_str().cmp(artist_name))
|
||||
} else {
|
||||
slice.binary_search_by(|probe| {
|
||||
probe
|
||||
.get_sort_key()
|
||||
.name
|
||||
.to_lowercase()
|
||||
.as_str()
|
||||
.cmp(artist_name)
|
||||
})
|
||||
};
|
||||
let result = slice.binary_search_by(|probe| {
|
||||
Self::normalize_search_string(&probe.get_sort_key().name, !case_sensitive)
|
||||
.cmp(&search_name)
|
||||
});
|
||||
|
||||
let new_index = match result {
|
||||
Ok(slice_index) | Err(slice_index) => index + slice_index,
|
||||
|
Loading…
Reference in New Issue
Block a user