allframe_core/cache/
traits.rs1use std::{future::Future, pin::Pin, time::Duration};
4
5use serde::{de::DeserializeOwned, Serialize};
6
7pub trait Cache: Send + Sync {
12 fn get<T: DeserializeOwned + Send>(
16 &self,
17 key: &str,
18 ) -> Pin<Box<dyn Future<Output = Option<T>> + Send + '_>>;
19
20 fn set<T: Serialize + Send + Sync>(
25 &self,
26 key: &str,
27 value: &T,
28 ttl: Option<Duration>,
29 ) -> Pin<Box<dyn Future<Output = ()> + Send + '_>>;
30
31 fn delete(&self, key: &str) -> Pin<Box<dyn Future<Output = bool> + Send + '_>>;
35
36 fn exists(&self, key: &str) -> Pin<Box<dyn Future<Output = bool> + Send + '_>>;
38
39 fn get_many<T: DeserializeOwned + Send>(
43 &self,
44 keys: &[&str],
45 ) -> Pin<Box<dyn Future<Output = Vec<Option<T>>> + Send + '_>> {
46 let keys: Vec<String> = keys.iter().map(|k| k.to_string()).collect();
47 Box::pin(async move {
48 let mut results = Vec::with_capacity(keys.len());
49 for key in keys {
50 results.push(self.get(&key).await);
51 }
52 results
53 })
54 }
55
56 fn set_many<'a, T: Serialize + Send + Sync + 'a>(
61 &'a self,
62 entries: Vec<(String, T)>,
63 ttl: Option<Duration>,
64 ) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
65 Box::pin(async move {
66 for (key, value) in entries {
67 self.set(&key, &value, ttl).await;
68 }
69 })
70 }
71
72 fn delete_many(&self, keys: &[&str]) -> Pin<Box<dyn Future<Output = usize> + Send + '_>> {
76 let keys: Vec<String> = keys.iter().map(|k| k.to_string()).collect();
77 Box::pin(async move {
78 let mut count = 0;
79 for key in keys {
80 if self.delete(&key).await {
81 count += 1;
82 }
83 }
84 count
85 })
86 }
87
88 fn clear(&self) -> Pin<Box<dyn Future<Output = ()> + Send + '_>>;
90
91 fn len(&self) -> Pin<Box<dyn Future<Output = Option<usize>> + Send + '_>> {
95 Box::pin(async { None })
96 }
97
98 fn is_empty(&self) -> Pin<Box<dyn Future<Output = bool> + Send + '_>> {
100 Box::pin(async move { self.len().await.map(|n| n == 0).unwrap_or(true) })
101 }
102}
103
104pub trait CacheExt: Cache {
106 fn get_keyed<K: super::CacheKey, T: DeserializeOwned + Send>(
108 &self,
109 key: &K,
110 ) -> Pin<Box<dyn Future<Output = Option<T>> + Send + '_>> {
111 let key = key.cache_key();
112 Box::pin(async move { self.get(&key).await })
113 }
114
115 fn set_keyed<'a, K: super::CacheKey, T: Serialize + Send + Sync + 'a>(
117 &'a self,
118 key: &K,
119 value: T,
120 ttl: Option<Duration>,
121 ) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
122 let key = key.cache_key();
123 Box::pin(async move { self.set(&key, &value, ttl).await })
124 }
125
126 fn delete_keyed<K: super::CacheKey>(
128 &self,
129 key: &K,
130 ) -> Pin<Box<dyn Future<Output = bool> + Send + '_>> {
131 let key = key.cache_key();
132 Box::pin(async move { self.delete(&key).await })
133 }
134}
135
136impl<C: Cache + ?Sized> CacheExt for C {}
138
139pub type CacheResult<T> = Result<T, CacheError>;
141
142#[derive(Debug, Clone)]
144pub enum CacheError {
145 Serialization(String),
147 Deserialization(String),
149 Connection(String),
151 Timeout,
153 Other(String),
155}
156
157impl std::fmt::Display for CacheError {
158 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
159 match self {
160 CacheError::Serialization(msg) => write!(f, "Serialization error: {}", msg),
161 CacheError::Deserialization(msg) => write!(f, "Deserialization error: {}", msg),
162 CacheError::Connection(msg) => write!(f, "Connection error: {}", msg),
163 CacheError::Timeout => write!(f, "Operation timed out"),
164 CacheError::Other(msg) => write!(f, "Cache error: {}", msg),
165 }
166 }
167}
168
169impl std::error::Error for CacheError {}
170
171#[cfg(test)]
172mod tests {
173 use super::*;
174
175 #[test]
176 fn test_cache_error_display() {
177 let err = CacheError::Connection("refused".into());
178 assert!(err.to_string().contains("refused"));
179 }
180}