1use std::time::Duration;
2
3use crate::{drivers::MemoryDriver, CacheError};
4
5#[cfg(feature = "redis")]
6use crate::drivers::RedisDriver;
7
8#[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
55pub 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#[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}