use super::{MetadataProvider, MetadataRetrievalError, TVSeries};
use crate::cache::CacheStorage;
pub(crate) struct CachedMetadataProvider<P>
where
P: MetadataProvider,
{
provider: P,
cache: CacheStorage<TVSeries>,
}
impl<P> CachedMetadataProvider<P>
where
P: MetadataProvider,
{
pub fn new(provider: P, cache: CacheStorage<TVSeries>) -> Self {
Self { provider, cache }
}
fn cache_key(series_name: &str, season_numbers: &Option<Vec<usize>>) -> String {
match season_numbers {
None => series_name.to_string(),
Some(seasons) => {
let mut seasons_sorted = seasons.clone();
seasons_sorted.sort_unstable();
format!(
"{}_seasons_{}",
series_name,
seasons_sorted
.iter()
.map(|s| s.to_string())
.collect::<Vec<_>>()
.join("_")
)
}
}
}
}
impl<P> MetadataProvider for CachedMetadataProvider<P>
where
P: MetadataProvider,
{
fn fetch_series(
&self,
series_name: &str,
season_numbers: Option<Vec<usize>>,
) -> Result<TVSeries, MetadataRetrievalError> {
let cache_key = Self::cache_key(series_name, &season_numbers);
match self.cache.load(&cache_key) {
Ok(Some(series)) => {
return Ok(series);
}
Ok(None) => {
}
Err(_) => {
}
}
let series = self.provider.fetch_series(series_name, season_numbers)?;
let _ = self.cache.store(&cache_key, &series);
Ok(series)
}
}