1extern crate r2d2;
2extern crate redis;
3extern crate dns_lookup;
4extern crate parking_lot;
5
6pub use redis::Value;
7pub use redis::FromRedisValue as FromValue;
8pub use redis::ToRedisArgs as ToArgs;
9
10mod error;
11mod memory_cache;
12mod redis_cache;
13
14use std::{any::Any, collections::HashMap};
15
16use crate::memory_cache::MemoryCache;
17use crate::redis_cache::RedisCache;
18pub use crate::error::CacheError;
19
20pub type Result<T> = std::result::Result<T, CacheError>;
21
22pub trait Cacheable {
23 fn model_name() -> &'static str where Self: Sized;
24 fn to_redis_obj(&self) -> Vec<(String, String)>;
25 fn from_redis_obj(obj: HashMap<String, String>) -> Result<Self> where Self: Sized;
26 fn expires_after(&self) -> Option<usize>;
27 fn as_any(&self) -> &dyn Any;
28}
29
30use std::str::FromStr;
31
32pub trait CacheFunc {
33 fn hash_delete(&self, key: &str, fields: &[&str]) -> Result<bool>;
35 fn hash_exists(&self, key: &str, field: &str) -> Result<bool>;
36 fn hash_get<T: FromStr>(&self, key: &str, field: &str) -> Result<Option<T>>;
37 fn hash_get_all<T: Cacheable + Clone + 'static>(&self, key: &str) -> Result<Option<T>>;
38 fn hash_keys(&self, key: &str) -> Result<Vec<String>>;
39 fn hash_len(&self, key: &str) -> Result<usize>;
40 fn hash_multiple_get(&self, key: &str, fields: &[&str]) -> Result<Vec<Option<String>>>;
41 fn hash_multiple_set<V: ToString>(&self, key: &str, fv_pairs: &[(&str, V)] ) -> Result<bool>;
42 fn hash_set<V: ToString>(&self, key: &str, field: &str, value: V) -> Result<bool>;
43 fn hash_set_all<T: Cacheable + Clone + 'static>(&self, key: &str, cacheable: T) -> Result<bool>;
44 fn hash_set_if_not_exists<V: ToString>(&self, key: &str, field: &str, value: V) -> Result<bool>;
45 fn hash_values(&self, key: &str) -> Result<Vec<String>>;
46 fn set_add<V: ToString>(&self, key: &str, members: &[V]) -> Result<bool>;
48 fn set_card(&self, key: &str) -> Result<u64>;
49 fn set_diff(&self, keys: &[&str]) -> Result<Vec<String>>;
50 fn set_diffstore(&self, diff_name: &str, keys: &[&str]) -> Result<u64>;
51 fn set_inter(&self, keys: &[&str]) -> Result<Vec<String>>;
52 fn set_interstore(&self, inter_name: &str, keys: &[&str]) -> Result<u64>;
53 fn set_ismember<V: ToString>(&self, key: &str, member: V) -> Result<bool>;
54 fn set_members(&self, key: &str) -> Result<Vec<String>>;
55 fn set_move<V: ToString>(&self, key1: &str, key2: &str, member: V) -> Result<bool>;
56 fn set_rem<V: ToString>(&self, key: &str, member: V) -> Result<bool>;
57 fn set_union(&self, keys: &[&str]) -> Result<Vec<String>>;
58 fn set_unionstore(&self, union_name: &str, keys: &[&str]) -> Result<u64>;
59
60}
61
62trait CacheAccess {
63 fn insert<K: ToString, O: Cacheable + Clone + 'static>(&self, key: K, obj: O) -> Result<()>;
64 fn insert_with<K: ToString, O: Cacheable + Clone + 'static>(&self, key: K, obj: O, expires_after: Option<usize>) -> Result<()>;
65 fn get<K: ToString, O: Cacheable + Clone + 'static>(&self, key: K) -> Result<Option<O>>;
66 fn contains_key<K: ToString, O: Cacheable + Clone + 'static>(&self, key: K) -> Result<bool>;
67 fn remove<K: ToString, O: Cacheable>(&self, key: K) -> Result<()>;
68}
69
70pub enum Cache {
71 Memory(MemoryCache),
72 Redis(RedisCache),
73}
74
75impl Clone for Cache {
76 fn clone(&self) -> Self {
77 match *self {
78 Memory(ref c) => Memory(c.clone()),
79 Redis(ref c) => Redis(c.clone()),
80 }
81 }
82}
83
84use crate::Cache::*;
85
86impl Cache {
87 pub fn insert<K: ToString, O: Cacheable + Clone + 'static>(&self, key: K, obj: O) -> Result<()> {
88 match *self {
89 Memory(ref c) => c.insert(key, obj),
90 Redis(ref c) => c.insert(key, obj),
91 }
92 }
93
94 pub fn insert_with<K: ToString, O: Cacheable + Clone + 'static>(&self, key: K, obj: O, expires_after: Option<usize>) -> Result<()> {
95 match *self {
96 Memory(ref c) => c.insert_with(key, obj, expires_after),
97 Redis(ref c) => c.insert_with(key, obj, expires_after),
98 }
99 }
100
101 pub fn get<K: ToString, O: Cacheable + Clone + 'static>(&self, key: K) -> Result<Option<O>> {
102 match *self {
103 Memory(ref c) => c.get::<K, O>(key),
104 Redis(ref c) => c.get::<K, O>(key),
105 }
106 }
107
108 pub fn remove<K: ToString, O: Cacheable>(&self, key: K) -> Result<()> {
109 match *self {
110 Memory(ref c) => c.remove::<K, O>(key),
111 Redis(ref c) => c.remove::<K, O>(key),
112 }
113 }
114}
115
116impl CacheFunc for Cache {
117 fn hash_delete(&self, key: &str, fields: &[&str]) -> Result<bool> {
118 match *self {
119 Memory(ref m) => m.hash_delete(key, fields),
120 Redis(ref r) => r.hash_delete(key, fields),
121 }
122 }
123
124 fn hash_exists(&self, key: &str, field: &str) -> Result<bool> {
125 match *self {
126 Memory(ref m) => m.hash_exists(key, field),
127 Redis(ref r) => r.hash_exists(key, field),
128 }
129 }
130
131 fn hash_get<T: FromStr>(&self, key: &str, field: &str) -> Result<Option<T>> {
132 match *self {
133 Memory(ref m) => m.hash_get(key, field),
134 Redis(ref r) => r.hash_get(key, field),
135 }
136 }
137
138 fn hash_get_all<T: Cacheable + Clone + 'static>(&self, key: &str) -> Result<Option<T>> {
139 match *self {
140 Memory(ref m) => m.hash_get_all(key),
141 Redis(ref r) => r.hash_get_all(key),
142 }
143 }
144
145 fn hash_keys(&self, key: &str) -> Result<Vec<String>> {
146 match *self {
147 Memory(ref m) => m.hash_keys(key),
148 Redis(ref r) => r.hash_keys(key),
149 }
150 }
151
152 fn hash_len(&self, key: &str) -> Result<usize> {
153 match *self {
154 Memory(ref m) => m.hash_len(key),
155 Redis(ref r) => r.hash_len(key),
156 }
157 }
158
159 fn hash_multiple_get(&self, key: &str, fields: &[&str]) -> Result<Vec<Option<String>>> {
160 match *self {
161 Memory(ref m) => m.hash_multiple_get(key, fields),
162 Redis(ref r) => r.hash_multiple_get(key, fields),
163 }
164 }
165
166 fn hash_multiple_set<V: ToString>(&self, key: &str, fv_pairs: &[(&str, V)]) -> Result<bool> {
167 match *self {
168 Memory(ref m) => m.hash_multiple_set(key, fv_pairs),
169 Redis(ref r) => r.hash_multiple_set(key, fv_pairs),
170 }
171 }
172
173 fn hash_set<V: ToString>(&self, key: &str, field: &str, value: V) -> Result<bool> {
174 match *self {
175 Memory(ref m) => m.hash_set(key, field, value),
176 Redis(ref r) => r.hash_set(key, field, value),
177 }
178 }
179
180 fn hash_set_all<T: Cacheable + Clone + 'static>(&self, key: &str, cacheable: T) -> Result<bool> {
181 match *self {
182 Memory(ref m) => m.hash_set_all(key, cacheable),
183 Redis(ref r) => r.hash_set_all(key, cacheable),
184 }
185 }
186
187 fn hash_set_if_not_exists<V: ToString>(&self, key: &str, field: &str, value: V) -> Result<bool> {
188 match *self {
189 Memory(ref m) => m.hash_set_if_not_exists(key, field, value),
190 Redis(ref r) => r.hash_set_if_not_exists(key, field, value),
191 }
192 }
193
194 fn hash_values(&self, key: &str) -> Result<Vec<String>> {
195 match *self {
196 Memory(ref m) => m.hash_values(key),
197 Redis(ref r) => r.hash_values(key),
198 }
199 }
200
201 fn set_add<V: ToString>(&self, key: &str, members: &[V]) -> Result<bool> {
202 match *self {
203 Memory(ref m) => m.set_add(key, members),
204 Redis(ref r) => r.set_add(key, members),
205 }
206 }
207
208 fn set_card(&self, key: &str) -> Result<u64> {
209 match *self {
210 Memory(ref m) => m.set_card(key),
211 Redis(ref r) => r.set_card(key),
212 }
213 }
214
215 fn set_diff(&self, keys: &[&str]) -> Result<Vec<String>> {
216 match *self {
217 Memory(ref m) => m.set_diff(keys),
218 Redis(ref r) => r.set_diff(keys),
219 }
220 }
221
222 fn set_diffstore(&self, diff_name: &str, keys: &[&str]) -> Result<u64> {
223 match *self {
224 Memory(ref m) => m.set_diffstore(diff_name, keys),
225 Redis(ref r) => r.set_diffstore(diff_name, keys),
226 }
227 }
228
229 fn set_inter(&self, keys: &[&str]) -> Result<Vec<String>> {
230 match *self {
231 Memory(ref m) => m.set_inter(keys),
232 Redis(ref r) => r.set_inter(keys),
233 }
234 }
235
236 fn set_interstore(&self, inter_name: &str, keys: &[&str]) -> Result<u64> {
237 match *self {
238 Memory(ref m) => m.set_interstore(inter_name, keys),
239 Redis(ref r) => r.set_interstore(inter_name, keys),
240 }
241 }
242
243 fn set_ismember<V: ToString>(&self, key: &str, member: V) -> Result<bool> {
244 match *self {
245 Memory(ref m) => m.set_ismember(key, member),
246 Redis(ref r) => r.set_ismember(key, member),
247 }
248 }
249
250 fn set_members(&self, key: &str) -> Result<Vec<String>> {
251 match *self {
252 Memory(ref m) => m.set_members(key),
253 Redis(ref r) => r.set_members(key),
254 }
255 }
256
257 fn set_move<V: ToString>(&self, key1: &str, key2: &str, member: V) -> Result<bool> {
258 match *self {
259 Memory(ref m) => m.set_move(key1, key2, member),
260 Redis(ref r) => r.set_move(key1, key2, member),
261 }
262 }
263
264 fn set_rem<V: ToString>(&self, key: &str, member: V) -> Result<bool> {
265 match *self {
266 Memory(ref m) => m.set_rem(key, member),
267 Redis(ref r) => r.set_rem(key, member),
268 }
269 }
270
271 fn set_union(&self, keys: &[&str]) -> Result<Vec<String>> {
272 match *self {
273 Memory(ref m) => m.set_union(keys),
274 Redis(ref r) => r.set_union(keys),
275 }
276 }
277
278 fn set_unionstore(&self, union_name: &str, keys: &[&str]) -> Result<u64> {
279 match *self {
280 Memory(ref m) => m.set_unionstore(union_name, keys),
281 Redis(ref r) => r.set_unionstore(union_name, keys),
282 }
283 }
284}
285
286unsafe impl Send for Cache {}
287unsafe impl Sync for Cache {}
288
289pub fn memory() -> Cache {
290 Memory(MemoryCache::new())
291}
292
293pub fn redis(host: &str, password: Option<&str>, db: Option<u16>) -> Result<Cache> {
294 match RedisCache::new(host, password, db) {
295 Ok(rc) => Ok(Redis(rc)),
296 Err(e) => Err(e),
297 }
298}