ralertsinua_http/
cache.rs

1#![cfg(feature = "cache")]
2
3use bytes::Bytes;
4use quick_cache::sync::Cache;
5use std::{fmt, sync::Arc};
6
7use crate::ApiError;
8
9type Result<T> = miette::Result<T, ApiError>;
10type LastModified = String;
11type ApiCache = Cache<String, (Bytes, LastModified)>;
12
13#[derive(Debug)]
14pub struct CacheEntry(pub Bytes, pub LastModified);
15
16/// A trait providing methods for storing, reading, and removing cache records.
17pub trait CacheManagerSync: Send + Sync + 'static {
18    /// Attempts to pull a cached response and related last_modified from cache.
19    fn get(&self, cache_key: &str) -> Result<Option<CacheEntry>>;
20    /// Attempts to cache a response and related last_modified.
21    fn put(&self, cache_key: &str, last_modified: &str, bytes: Bytes) -> Result<()>;
22    /// Attempts to remove a record from cache.
23    fn delete(&self, cache_key: &str) -> Result<()>;
24}
25
26/// Implements [`CacheManager`] with [`quick-cache`](https://github.com/arthurprs/quick-cache) as the backend.
27#[derive(Clone)]
28pub struct CacheManagerQuick {
29    /// The instance of `quick_cache::sync::Cache`
30    pub cache: Arc<ApiCache>,
31}
32
33impl fmt::Debug for CacheManagerQuick {
34    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
35        // need to add more data, anything helpful
36        f.debug_struct("QuickManager").finish_non_exhaustive()
37    }
38}
39
40impl CacheManagerQuick {
41    /// Create a new manager from a pre-configured Cache
42    pub fn new(capacity: usize) -> Self {
43        Self {
44            cache: Arc::new(Cache::new(capacity)),
45        }
46    }
47}
48
49impl CacheManagerSync for CacheManagerQuick {
50    fn get(&self, cache_key: &str) -> Result<Option<CacheEntry>> {
51        let entry: CacheEntry = match self.cache.get(cache_key) {
52            Some((bytes, lm)) => CacheEntry(bytes, lm),
53            None => return Ok(None),
54        };
55        Ok(Some(entry))
56    }
57
58    fn put(&self, cache_key: &str, last_modified: &str, bytes: Bytes) -> Result<()> {
59        self.cache
60            .insert(cache_key.into(), (bytes, last_modified.into()));
61        Ok(())
62    }
63
64    fn delete(&self, cache_key: &str) -> Result<()> {
65        self.cache.remove(cache_key);
66        Ok(())
67    }
68}
69
70// The existence of this function makes the compiler catch if the Buf
71// trait is "object-safe" or not.
72fn _assert_trait_object(_: &dyn CacheManagerSync) {}