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) {
|
fn incremental_search(&mut self, artists: &[Artist], artist_name: &str) {
|
||||||
if let Some(index) = self.state.list.selected() {
|
if let Some(index) = self.state.list.selected() {
|
||||||
let case_sensitive = artist_name
|
let case_sensitive = artist_name
|
||||||
.chars()
|
.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 slice = &artists[index..];
|
||||||
|
|
||||||
let result = if case_sensitive {
|
let result = slice.binary_search_by(|probe| {
|
||||||
slice.binary_search_by(|probe| probe.get_sort_key().name.as_str().cmp(artist_name))
|
Self::normalize_search_string(&probe.get_sort_key().name, !case_sensitive)
|
||||||
} else {
|
.cmp(&search_name)
|
||||||
slice.binary_search_by(|probe| {
|
});
|
||||||
probe
|
|
||||||
.get_sort_key()
|
|
||||||
.name
|
|
||||||
.to_lowercase()
|
|
||||||
.as_str()
|
|
||||||
.cmp(artist_name)
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
let new_index = match result {
|
let new_index = match result {
|
||||||
Ok(slice_index) | Err(slice_index) => index + slice_index,
|
Ok(slice_index) | Err(slice_index) => index + slice_index,
|
||||||
|
Loading…
Reference in New Issue
Block a user