use crate::errors::*; use std::{cell::RefCell, hash::Hash, num::NonZeroUsize, rc::Rc}; use lru::LruCache; use crate::data_loader::Data; pub struct Cache { cache: LruCache, } impl Cache { pub fn new() -> Self { Self { cache: LruCache::new(NonZeroUsize::new(10).unwrap()), } } pub fn get(&mut self, key: &K) -> Option<&V> { self.cache.get(key) } pub fn get_mut(&mut self, key: &K) -> Option<&mut V> { self.cache.get_mut(key) } } impl Cache where K: AsRef + Hash + Eq + Clone, V: CacheData, { pub fn insert(&mut self, key: K) -> Result<()> { let value = V::from_path(&key)?; self.cache.put(key, value); Ok(()) } pub fn get_or_insert(&mut self, key: K) -> Result<&V> { if !self.cache.contains(&key) { self.insert(key.clone())?; } Ok(self.cache.get(&key).unwrap()) } } pub type CachedData = Rc>; pub trait CacheData: Sized { fn from_path(path: impl AsRef) -> Result; } impl CacheData for Data { fn from_path(path: impl AsRef) -> Result { Data::from_path(path) } } impl CacheData for CachedData { fn from_path(path: impl AsRef) -> Result { Ok(Rc::new(RefCell::new(T::from_path(path)?))) } }