Skip to main content

rok_cache/
driver.rs

1use std::time::Duration;
2
3use crate::{drivers::MemoryDriver, CacheError};
4
5#[cfg(feature = "redis")]
6use crate::drivers::RedisDriver;
7
8/// Enum-dispatched driver. Cheap to clone (Arc-backed internals).
9#[derive(Clone)]
10pub enum Driver {
11    Memory(MemoryDriver),
12    #[cfg(feature = "redis")]
13    Redis(RedisDriver),
14}
15
16impl Driver {
17    pub async fn get(&self, key: &str) -> Result<Option<String>, CacheError> {
18        match self {
19            Driver::Memory(d) => d.get(key).await,
20            #[cfg(feature = "redis")]
21            Driver::Redis(d) => d.get(key).await,
22        }
23    }
24
25    pub async fn set(
26        &self,
27        key: &str,
28        value: String,
29        ttl: Option<Duration>,
30    ) -> Result<(), CacheError> {
31        match self {
32            Driver::Memory(d) => d.set(key, value, ttl).await,
33            #[cfg(feature = "redis")]
34            Driver::Redis(d) => d.set(key, value, ttl).await,
35        }
36    }
37
38    pub async fn forget(&self, key: &str) -> Result<(), CacheError> {
39        match self {
40            Driver::Memory(d) => d.forget(key).await,
41            #[cfg(feature = "redis")]
42            Driver::Redis(d) => d.forget(key).await,
43        }
44    }
45
46    pub async fn flush(&self) -> Result<(), CacheError> {
47        match self {
48            Driver::Memory(d) => d.flush().await,
49            #[cfg(feature = "redis")]
50            Driver::Redis(d) => d.flush().await,
51        }
52    }
53}
54
55/// Build a driver from config strings.  Falls back to `Memory` for unknown names.
56pub fn build_driver(name: &str, redis_url: Option<&str>) -> Result<Driver, CacheError> {
57    match name {
58        #[cfg(feature = "redis")]
59        "redis" => {
60            let url = redis_url.ok_or(CacheError::MissingRedisUrl)?;
61            Ok(Driver::Redis(RedisDriver::new(url)?))
62        }
63        _ => Ok(Driver::Memory(MemoryDriver::new())),
64    }
65}
66
67/// Bundles a driver with a key prefix.  Stored task-locally by `CacheLayer`.
68#[derive(Clone)]
69pub struct CacheHandle {
70    pub(crate) driver: Driver,
71    pub(crate) prefix: String,
72}
73
74impl CacheHandle {
75    pub fn new(driver: Driver, prefix: impl Into<String>) -> Self {
76        Self {
77            driver,
78            prefix: prefix.into(),
79        }
80    }
81
82    pub(crate) fn key(&self, k: &str) -> String {
83        if self.prefix.is_empty() {
84            k.to_string()
85        } else {
86            format!("{}{}", self.prefix, k)
87        }
88    }
89}