use std::{future::Future, time::*, collections::HashMap, hash::Hash}; #[derive(Debug)] pub struct AsyncCache { func: F, cache: HashMap, interval: Duration } impl AsyncCache where F: for<'a> FnMut(&'a K) -> Fut, K: Hash + PartialEq + Eq + Clone, Fut: Future> { pub fn new(interval: Duration, func: F) -> Self { Self{ cache: HashMap::new(), interval, func } } pub async fn get(&mut self, key: &K) -> Result<&V, &'static str> { if self.is_stale(&key) { self.renew(&key).await } else { Ok(&self.cache.get(&key).unwrap().1) } } pub async fn renew(&mut self, key: &K) -> Result<&V, &'static str> { let val = (self.func)(&key).await?; self.cache.insert(key.clone(), (Instant::now(), val)); Ok(&self.cache.get(key).unwrap().1) } pub fn is_stale(&self, key: &K) -> bool { if let Some((last_update, _)) = self.cache.get(key) { let now = Instant::now(); now < (*last_update + self.interval) } else { true } } pub async fn get_opt(&self, key: &K) -> Option<&V> { if self.is_stale(key) { self.cache.get(key).map(|(_, v)| v) } else { None } } } impl AsyncCache where F: for<'a> FnMut(&'a K) -> Fut, K: Hash + PartialEq + Eq + Clone, V: Clone, Fut: Future> { pub async fn get_owned(&mut self, key: &K) -> Result { self.get(key).await.cloned() } } /* pub struct AsyncCache { func: F, cache: HashMap, interval: Duration } impl AsyncCache where for<'a> F: FnMut(&'a K) -> Fut + 'a, Fut: Future { pub fn new(interval: Duration, mut func: F) -> Self { Self{ cache: HashMap::new(), interval, func } } pub async fn get(&mut self, key: &K) -> &V { if self.is_stale(key) { self.renew().await } else { self.cache.get(key) } } pub async fn renew(&mut self, key: &K) -> &V { self.cache.get_mut(key).0 = now; self.cache.get_mut(key).1 = (self.func)(key).await; self.cache.get(key) } pub fn is_stale(&self, key: &K) -> bool { let now = Instant::now(); let last_update = self.cache.get(key).0; now < (last_update + self.interval) } pub fn get_opt(&self, key: &K) -> Option<&T> { if self.is_stale(key) { Some(self.cache.get(key)) } else { None } } } impl AsyncCache where F: for<'a> FnMut(&'a K) -> Fut + 'a, Fut: Future, V: Clone { pub async fn get_owned(&mut self, key: &K) -> V { self.get(key).await.clone() } } */