Skip to content

Commit d423bdd

Browse files
committed
Added lyrics cache to LyricsManager
1 parent d18b8ba commit d423bdd

File tree

1 file changed

+35
-8
lines changed

1 file changed

+35
-8
lines changed

src/lyrics.rs

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
use std::sync::Arc;
1+
use log::trace;
2+
use std::{cell::RefCell, collections::HashMap, sync::Arc};
23

34
use crate::{
45
lyrics_fetcher::LyricsFetcher,
@@ -10,26 +11,52 @@ use crate::{
1011
pub struct LyricsManager {
1112
queue: Arc<Queue>,
1213
fetcher: LyricsFetcher,
13-
// TODO: add a cache
14+
cache: RefCell<HashMap<String, String>>,
1415
}
1516

1617
impl LyricsManager {
1718
pub fn new(queue: Arc<Queue>, fetcher: LyricsFetcher) -> Self {
18-
LyricsManager { queue, fetcher }
19+
LyricsManager {
20+
queue,
21+
fetcher,
22+
cache: RefCell::new(HashMap::new()),
23+
}
1924
}
2025

2126
/// Saves the given lyrics to the user's filesystem.
2227
///
2328
/// Returns an optional message indicating the outcome of this operation.
2429
pub fn save_lyrics(&self, lyrics: String) -> Option<String> {
25-
Some("".to_string())
30+
Some(lyrics)
2631
}
2732

2833
/// Fetches and returns the lyrics of the given track
2934
pub fn get_lyrics(&self, track: Track) -> String {
30-
// TODO: implement caching
35+
// TODO: see if this panics later on
36+
let track_id = track.id.as_ref().unwrap();
37+
38+
{
39+
// insert new scope so that we can perform both borrows from the RefCell
40+
// the immutable borrow present in this scope is dropped,
41+
// so it is safe to do another borrow after
42+
43+
let cache = self.cache.borrow();
44+
45+
if cache.contains_key(track_id) {
46+
trace!("Retrieving cached lyrics for {}", track.title);
47+
return cache.get(track_id).unwrap().to_owned();
48+
}
49+
}
50+
51+
// if we reach this point it means that the cache does not contain this entry yet, update it
52+
let mut cache = self.cache.borrow_mut();
53+
54+
// make network request to fetch track's lyrics
55+
let lyrics = self.fetcher.fetch(&track);
56+
57+
cache.insert(track_id.to_owned(), lyrics.clone());
3158

32-
self.fetcher.fetch(&track)
59+
lyrics
3360
}
3461

3562
/// Fetches and returns the lyrics of the currently playing track
@@ -40,13 +67,13 @@ impl LyricsManager {
4067
}
4168
}
4269

43-
/// Returns the track being played currently, or nothing if the user is listening to a podcast episodes
70+
/// Returns the track being played currently, or nothing if the user is listening to a podcast episode
4471
pub fn get_current_track(&self) -> Option<Track> {
4572
let playable = self.queue.get_current().unwrap();
4673

4774
match playable {
4875
Playable::Track(track) => Some(track),
49-
Playable::Episode(_) => None,
76+
_ => None,
5077
}
5178
}
5279
}

0 commit comments

Comments
 (0)