Improve search
This commit is contained in:
55
src/song.rs
55
src/song.rs
@ -1,4 +1,5 @@
|
||||
use crate::fuzzy::{self, FuzzyScore};
|
||||
use crate::query::ParsedQuery;
|
||||
use serde::Deserialize;
|
||||
use std::cmp::max;
|
||||
|
||||
@ -26,10 +27,56 @@ impl Song {
|
||||
.zip(self.duet_singer_2.as_deref())
|
||||
}
|
||||
|
||||
pub fn fuzzy_compare(&self, query: &str) -> FuzzyScore {
|
||||
let title_score = fuzzy::compare(self.title.chars(), query.chars());
|
||||
let artist_score = fuzzy::compare(self.artist.chars(), query.chars());
|
||||
pub fn fuzzy_compare(&self, query: &ParsedQuery) -> FuzzyScore {
|
||||
let bad = || -1;
|
||||
|
||||
max(title_score, artist_score)
|
||||
let filter_strs = |query: Option<&str>, item: Option<&str>| {
|
||||
if let Some(query) = query {
|
||||
match item {
|
||||
Some(item) => {
|
||||
let score = fuzzy::compare(item.chars(), query.chars());
|
||||
if score < fuzzy::max_score(query) / 2 {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
None => return false,
|
||||
}
|
||||
}
|
||||
true
|
||||
};
|
||||
|
||||
let filter_bool =
|
||||
|query: Option<bool>, item| !matches!(query, Some(query) if query != item);
|
||||
|
||||
let filters: &[&dyn Fn() -> bool] = &[
|
||||
&|| filter_bool(query.duet, self.duet().is_some()),
|
||||
&|| filter_bool(query.video, self.video.is_some()),
|
||||
&|| filter_strs(query.language, self.language.as_deref()),
|
||||
&|| filter_strs(query.genre, self.genre.as_deref()),
|
||||
&|| filter_strs(query.year, self.year.as_deref()),
|
||||
];
|
||||
|
||||
if !filters.iter().all(|f| f()) {
|
||||
return bad();
|
||||
}
|
||||
|
||||
let mut score = FuzzyScore::default();
|
||||
if let Some(plain) = &query.plain {
|
||||
let title_score = fuzzy::compare(self.title.chars(), plain.chars());
|
||||
let artist_score = fuzzy::compare(self.artist.chars(), plain.chars());
|
||||
score = max(title_score, artist_score);
|
||||
}
|
||||
|
||||
if let Some(title) = query.title {
|
||||
let new_score = fuzzy::compare(self.title.chars(), title.chars());
|
||||
score = max(score, new_score);
|
||||
}
|
||||
|
||||
if let Some(artist) = query.artist {
|
||||
let new_score = fuzzy::compare(self.artist.chars(), artist.chars());
|
||||
score = max(score, new_score);
|
||||
}
|
||||
|
||||
score
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user