mem_cache/cache/
cache_item.rs

1use std::time::{SystemTime, UNIX_EPOCH, Duration};
2
3pub struct CacheItem<T> {
4  begin_secs: u64,
5  expires_in_secs: Duration,
6  calculation: Box<dyn Fn() -> T>,
7  value: Option<T>,
8}
9impl<T> CacheItem<T> {
10  pub fn new(expires_in_secs: u64, calculation: impl Fn() -> T + 'static) -> Self {
11    CacheItem {
12          begin_secs: 0,
13          expires_in_secs: Duration::new(expires_in_secs, 0),
14          calculation: Box::new(calculation),
15          value: None
16      }
17  }
18  pub fn is_value_expired(&mut self) -> bool {
19      let current_secs = SystemTime::now().duration_since(UNIX_EPOCH).expect("Time went backwards").as_secs();
20      if current_secs >= self.begin_secs + self.expires_in_secs.as_secs() {
21          true
22      } else {
23          false
24      }
25  }
26  pub fn update_value(&mut self, value: T) {
27    self.begin_secs = SystemTime::now().duration_since(UNIX_EPOCH).expect("Time went backwards").as_secs();
28    self.value = Some(value);
29  }
30  pub fn expire_value(&mut self) {
31    self.begin_secs = 0;
32    self.value = None;
33  }
34  pub fn value(&mut self) -> &T {
35      self.value.get_or_insert_with(|| {
36          let v = (self.calculation)();
37          self.begin_secs = SystemTime::now().duration_since(UNIX_EPOCH).expect("Time went backwards").as_secs();
38          v
39      })
40  }
41//   pub fn expires_in_secs(&self) -> u64 {
42//       self.expires_in_secs.as_secs()
43//   }
44}
45
46#[cfg(test)]
47mod tests {
48  use super::*;
49
50  #[test]
51  fn test_cache_item() {
52      let mut i32_cache_item = CacheItem::new(10, || 5);
53      assert_eq!(i32_cache_item.value(), &5);
54  }
55}