1- use std:: sync:: Arc ;
1+ use log:: trace;
2+ use std:: { cell:: RefCell , collections:: HashMap , sync:: Arc } ;
23
34use crate :: {
45 lyrics_fetcher:: LyricsFetcher ,
@@ -10,26 +11,52 @@ use crate::{
1011pub struct LyricsManager {
1112 queue : Arc < Queue > ,
1213 fetcher : LyricsFetcher ,
13- // TODO: add a cache
14+ cache : RefCell < HashMap < String , String > > ,
1415}
1516
1617impl 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