use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use super::{JsonStore, StoreLocation};
use crate::lyrics::{Lyrics, LyricsProvider};
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct CachedLyrics {
pub plain: String,
pub timed: Vec<(f32, String)>,
pub provider: LyricsProvider,
}
impl CachedLyrics {
pub fn to_lyrics(&self) -> Lyrics {
Lyrics {
timed: self.timed.clone(),
plain: self.plain.clone(),
provider: self.provider,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct LyricsCache {
entries: HashMap<String, Vec<CachedLyrics>>,
}
impl JsonStore for LyricsCache {
const FILE: &'static str = "lyrics_cache.json";
const LOCATION: StoreLocation = StoreLocation::Cache;
}
impl LyricsCache {
pub fn get_for(&self, track_id: &str, provider: LyricsProvider) -> Option<Lyrics> {
self.entries
.get(track_id)
.and_then(|list| list.iter().find(|e| e.provider == provider))
.map(CachedLyrics::to_lyrics)
}
pub fn insert(&mut self, track_id: &str, lyrics: &Lyrics) {
let list = self.entries.entry(track_id.to_string()).or_default();
if let Some(slot) = list.iter_mut().find(|e| e.provider == lyrics.provider) {
slot.plain.clone_from(&lyrics.plain);
slot.timed.clone_from(&lyrics.timed);
} else {
list.push(CachedLyrics {
plain: lyrics.plain.clone(),
timed: lyrics.timed.clone(),
provider: lyrics.provider,
});
}
self.save();
}
}