use super::Searchers;
use super::compare_helper::MatchType;
#[derive(Debug, Clone)]
pub struct SearchResult {
pub searcher_type: Searchers,
pub title: String,
pub artists: Vec<String>,
pub album: String,
pub album_artists: Option<Vec<String>>,
pub duration_ms: Option<i32>,
pub match_type: Option<MatchType>,
pub id: String,
pub numeric_id: Option<i64>,
}
impl SearchResult {
pub fn new(
searcher_type: Searchers,
title: String,
artists: Vec<String>,
album: String,
duration_ms: Option<i32>,
id: String,
) -> Self {
Self {
searcher_type,
title,
artists,
album,
album_artists: None,
duration_ms,
match_type: None,
id,
numeric_id: None,
}
}
pub fn artist(&self) -> String {
self.artists.join(", ")
}
pub fn album_artist(&self) -> Option<String> {
self.album_artists.as_ref().map(|a| a.join(", "))
}
}
const ARTIST_SEPARATORS: [&str; 6] = [",", "、", "/", " & ", " feat. ", " ft. "];
pub fn split_artists(artists: &str) -> Vec<String> {
let mut parts = vec![artists];
for separator in ARTIST_SEPARATORS {
parts = parts
.into_iter()
.flat_map(|part| part.split(separator))
.collect();
}
parts
.into_iter()
.map(|part| part.trim().to_string())
.filter(|part| !part.is_empty())
.collect()
}
#[cfg(test)]
mod tests {
use super::split_artists;
#[test]
fn splits_on_every_supported_separator() {
assert_eq!(split_artists("周杰伦"), vec!["周杰伦".to_string()]);
assert_eq!(
split_artists("周杰伦、费玉清/方文山"),
vec![
"周杰伦".to_string(),
"费玉清".to_string(),
"方文山".to_string()
]
);
assert_eq!(
split_artists("Taylor Swift feat. Ed Sheeran & Future"),
vec![
"Taylor Swift".to_string(),
"Ed Sheeran".to_string(),
"Future".to_string()
]
);
assert!(split_artists(" , ").is_empty());
}
}