gr/cache/
inmemory.rs

1use std::{cell::RefCell, collections::HashMap};
2
3use crate::{
4    cache::{Cache, CacheState},
5    http::Resource,
6    io::{HttpResponse, ResponseField},
7};
8
9use crate::Result;
10
11pub struct InMemoryCache {
12    cache: RefCell<HashMap<String, HttpResponse>>,
13    expired: bool,
14    pub updated: RefCell<bool>,
15    pub updated_field: RefCell<ResponseField>,
16}
17
18impl Default for InMemoryCache {
19    fn default() -> Self {
20        Self {
21            cache: RefCell::new(HashMap::new()),
22            expired: false,
23            updated: RefCell::new(false),
24            // This is to verify we will get the headers updated in a 304
25            // response. Set it to Body, so we can verify headers are actually
26            // updated during tests. Might be better to have a builder pattern
27            // for this (TODO)
28            updated_field: RefCell::new(ResponseField::Body),
29        }
30    }
31}
32
33impl InMemoryCache {
34    pub fn expire(&mut self) {
35        self.expired = true;
36    }
37}
38
39impl Cache<Resource> for &InMemoryCache {
40    fn get(&self, key: &Resource) -> Result<CacheState> {
41        if let Some(response) = self.cache.borrow().get(&key.url) {
42            if self.expired {
43                return Ok(CacheState::Stale(response.clone()));
44            }
45            return Ok(CacheState::Fresh(response.clone()));
46        }
47        Ok(CacheState::None)
48    }
49
50    fn set(&self, key: &Resource, value: &HttpResponse) -> Result<()> {
51        self.cache
52            .borrow_mut()
53            .insert(key.url.to_string(), value.clone());
54        Ok(())
55    }
56
57    fn update(
58        &self,
59        key: &Resource,
60        value: &HttpResponse,
61        field: &crate::io::ResponseField,
62    ) -> Result<()> {
63        *self.updated.borrow_mut() = true;
64        *self.updated_field.borrow_mut() = field.clone();
65        self.set(key, value)
66    }
67}
68
69impl Cache<String> for InMemoryCache {
70    fn get(&self, key: &String) -> Result<CacheState> {
71        if let Some(response) = self.cache.borrow().get(key) {
72            if self.expired {
73                return Ok(CacheState::Stale(response.clone()));
74            }
75            return Ok(CacheState::Fresh(response.clone()));
76        }
77        Ok(CacheState::None)
78    }
79
80    fn set(&self, key: &String, value: &HttpResponse) -> Result<()> {
81        self.cache
82            .borrow_mut()
83            .insert(key.to_string(), value.clone());
84        Ok(())
85    }
86
87    fn update(
88        &self,
89        key: &String,
90        value: &HttpResponse,
91        _field: &crate::io::ResponseField,
92    ) -> Result<()> {
93        self.set(key, value)
94    }
95}