1use std::path::PathBuf;
2
3use sanitize_filename::sanitize;
4
5use crate::{config::lyrics_path, error::LyricsError, song::SongInfo};
6
7#[derive(Debug, Clone, Default)]
9pub struct CacheManager {
10 base_dir: PathBuf,
11}
12
13impl CacheManager {
14 pub fn new() -> Self {
15 Self {
16 base_dir: lyrics_path(),
17 }
18 }
19
20 fn lyrics_name(&self, song: &SongInfo) -> PathBuf {
21 let mut name = vec![sanitize(&song.artist), sanitize(&song.title)];
22 if !song.album.is_empty() {
23 name.push(sanitize(&song.album));
24 }
25 let file_name = format!("{}.lrc", name.join("-"));
26 let mut path = self.base_dir.clone();
27 path.push(file_name);
28 path
29 }
30
31 pub async fn get(&self, song: &SongInfo) -> Option<String> {
32 let path = self.lyrics_name(song);
33 if !path.exists() {
34 return None;
35 }
36 tokio::fs::read_to_string(&path).await.ok()
37 }
38
39 pub async fn store(
40 &self,
41 song: &SongInfo,
42 _source: &str,
43 content: &str,
44 ) -> Result<(), LyricsError> {
45 let path = self.lyrics_name(song);
46 tokio::fs::write(path, &content).await?;
47 Ok(())
48 }
49
50 pub async fn delete(&self, song: &SongInfo) {
51 let path = self.lyrics_name(song);
52 match tokio::fs::remove_file(path).await {
53 Ok(_) => {}
54 Err(e) => tracing::error!("delete file {} failed {}", song.title, e),
55 }
56 }
57}