http_cache/managers/
cacache.rs

1use std::path::PathBuf;
2
3use crate::{CacheManager, HttpResponse, Result};
4
5use http_cache_semantics::CachePolicy;
6use serde::{Deserialize, Serialize};
7
8/// Implements [`CacheManager`] with [`cacache`](https://github.com/zkat/cacache-rs) as the backend.
9#[derive(Clone)]
10pub struct CACacheManager {
11    /// Directory where the cache will be stored.
12    pub path: PathBuf,
13    /// Options for removing cache entries.
14    pub remove_opts: cacache::RemoveOpts,
15}
16
17impl std::fmt::Debug for CACacheManager {
18    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
19        f.debug_struct("CACacheManager").field("path", &self.path).finish()
20    }
21}
22
23#[derive(Debug, Deserialize, Serialize)]
24struct Store {
25    response: HttpResponse,
26    policy: CachePolicy,
27}
28
29#[allow(dead_code)]
30impl CACacheManager {
31    /// Creates a new [`CACacheManager`] with the given path.
32    pub fn new(path: PathBuf, remove_fully: bool) -> Self {
33        Self {
34            path,
35            remove_opts: cacache::RemoveOpts::new().remove_fully(remove_fully),
36        }
37    }
38
39    /// Clears out the entire cache.
40    pub async fn clear(&self) -> Result<()> {
41        cacache::clear(&self.path).await?;
42        Ok(())
43    }
44}
45
46#[async_trait::async_trait]
47impl CacheManager for CACacheManager {
48    async fn get(
49        &self,
50        cache_key: &str,
51    ) -> Result<Option<(HttpResponse, CachePolicy)>> {
52        let store: Store = match cacache::read(&self.path, cache_key).await {
53            Ok(d) => bincode::deserialize(&d)?,
54            Err(_e) => {
55                return Ok(None);
56            }
57        };
58        Ok(Some((store.response, store.policy)))
59    }
60
61    async fn put(
62        &self,
63        cache_key: String,
64        response: HttpResponse,
65        policy: CachePolicy,
66    ) -> Result<HttpResponse> {
67        let data = Store { response, policy };
68        let bytes = bincode::serialize(&data)?;
69        cacache::write(&self.path, cache_key, bytes).await?;
70        Ok(data.response)
71    }
72
73    async fn delete(&self, cache_key: &str) -> Result<()> {
74        self.remove_opts.clone().remove(&self.path, cache_key).await?;
75        Ok(())
76    }
77}