1use crate::redis::apply_operator;
3use redis::{Commands, RedisResult};
4use serde::{de::DeserializeOwned, Serialize};
5use std::fmt::{Debug, Display};
6use std::ops;
7
8pub struct Generic<T> {
14 pub(crate) cache: Option<T>,
15 pub(crate) key: String,
16 pub(crate) client: redis::Client,
17}
18
19impl<T> Generic<T>
20where
21 T: Serialize + DeserializeOwned,
22{
23 pub fn new(field_name: &str, client: redis::Client) -> Generic<T> {
39 Generic {
40 cache: None,
41 key: field_name.to_string(),
42 client,
43 }
44 }
45
46 pub fn with_value(value: T, field_name: &str, client: redis::Client) -> Generic<T> {
49 let mut new_type = Self::new(field_name, client);
50
51 new_type.store(value);
52 new_type
53 }
54
55 pub fn with_load(field_name: &str, client: redis::Client) -> Generic<T> {
59 let mut new_type = Self::new(field_name, client);
60
61 new_type.cache = new_type.try_get();
62 new_type
63 }
64
65 pub fn with_value_default(value: T, field_name: &str, client: redis::Client) -> Generic<T> {
69 let mut new_type = Self::new(field_name, client);
70
71 let v = new_type.try_get();
72 if v.is_none() {
73 new_type.store(value);
74 } else {
75 new_type.cache = v;
76 }
77
78 new_type
79 }
80
81 pub fn store(&mut self, value: T) {
83 let value = self.set(value);
84 self.cache = Some(value);
85 }
86
87 fn set(&self, value: T) -> T {
91 let mut conn = self.get_conn();
92 let v = serde_json::to_string(&value).expect("Failed to serialize value");
93 let res: RedisResult<()> = conn.set(&self.key, v);
94 res.expect("Failed to set value");
95 value
96 }
97
98 fn pushes_to_redis(&self) {
100 if self.cache.is_none() {
101 return;
102 }
103 let mut conn = self.get_conn();
104 let v = serde_json::to_string(&self.cache).expect("Failed to serialize value");
105 let res: RedisResult<()> = conn.set(&self.key, v);
106 res.expect("Failed to set value");
107 }
108
109 pub fn acquire(&mut self) -> &T {
123 self.cache = self.try_get();
124 self.cache.as_ref().unwrap()
125 }
126
127 fn try_get(&self) -> Option<T> {
128 let mut conn = self.get_conn();
129 let res: RedisResult<String> = conn.get(&self.key);
130 match res {
131 Ok(v) => {
132 let v: T = serde_json::from_str(&v).expect("Failed to deserialize value");
133 Some(v)
134 }
135 Err(_) => None,
136 }
137 }
138
139 pub fn into_inner(mut self) -> T {
153 let mut conn = self
154 .client
155 .get_connection()
156 .expect("Failed to get connection");
157 let _: RedisResult<()> = conn.del(&self.key);
158 self.cache.take().expect("Failed to get value")
159 }
160
161 pub(crate) fn get_conn(&self) -> redis::Connection {
164 self.client
165 .get_connection()
166 .expect("Failed to get connection")
167 }
168
169 pub fn cached(&self) -> Option<&T> {
171 self.cache.as_ref()
172 }
173}
174
175impl<T> ops::Deref for Generic<T>
176where
177 T: Display + Serialize + DeserializeOwned,
178{
179 type Target = T;
180
181 fn deref(&self) -> &Self::Target {
182 self.cached().expect("Failed to get value")
183 }
184}
185
186impl<T> ops::Add<T> for Generic<T>
187where
188 T: ops::Add<Output = T> + Display + Serialize + DeserializeOwned,
189{
190 type Output = Generic<T>;
191
192 fn add(self, rhs: T) -> Self::Output {
193 apply_operator(self, rhs, |a, b| a + b)
194 }
195}
196
197impl<T> ops::Add<Generic<T>> for Generic<T>
198where
199 T: ops::Add<Output = T> + Display + Serialize + DeserializeOwned,
200{
201 type Output = Generic<T>;
202
203 fn add(self, rhs: Generic<T>) -> Self::Output {
204 self + rhs.into_inner()
205 }
206}
207
208impl<T> ops::Sub<T> for Generic<T>
209where
210 T: ops::Sub<Output = T> + Display + Serialize + DeserializeOwned,
211{
212 type Output = Generic<T>;
213
214 fn sub(self, rhs: T) -> Self::Output {
215 apply_operator(self, rhs, |a, b| a - b)
216 }
217}
218
219impl<T> ops::Sub<Generic<T>> for Generic<T>
220where
221 T: ops::Sub<Output = T> + Display + Serialize + DeserializeOwned,
222{
223 type Output = Generic<T>;
224
225 fn sub(self, rhs: Generic<T>) -> Self::Output {
226 self - rhs.into_inner()
227 }
228}
229
230impl<T> ops::Mul<T> for Generic<T>
231where
232 T: ops::Mul<Output = T> + Display + Serialize + DeserializeOwned,
233{
234 type Output = Generic<T>;
235
236 fn mul(self, rhs: T) -> Self::Output {
237 apply_operator(self, rhs, |a, b| a * b)
238 }
239}
240
241impl<T> ops::Mul<Generic<T>> for Generic<T>
242where
243 T: ops::Mul<Output = T> + Display + Serialize + DeserializeOwned,
244{
245 type Output = Generic<T>;
246
247 fn mul(self, rhs: Generic<T>) -> Self::Output {
248 self * rhs.into_inner()
249 }
250}
251
252impl<T> ops::Div<T> for Generic<T>
253where
254 T: ops::Div<Output = T> + Display + Serialize + DeserializeOwned,
255{
256 type Output = Generic<T>;
257
258 fn div(self, rhs: T) -> Self::Output {
259 apply_operator(self, rhs, |a, b| a / b)
260 }
261}
262
263impl<T> ops::Div<Generic<T>> for Generic<T>
264where
265 T: ops::Div<Output = T> + Display + Serialize + DeserializeOwned,
266{
267 type Output = Generic<T>;
268
269 fn div(self, rhs: Generic<T>) -> Self::Output {
270 self / rhs.into_inner()
271 }
272}
273
274impl<T> ops::AddAssign<T> for Generic<T>
275where
276 T: ops::AddAssign + Display + Serialize + DeserializeOwned,
277{
278 fn add_assign(&mut self, rhs: T) {
279 if let Some(ref mut v) = self.cache {
280 *v += rhs;
281 } else {
282 self.cache = Some(rhs);
283 }
284
285 self.pushes_to_redis();
286 }
287}
288
289impl<T> ops::AddAssign<Generic<T>> for Generic<T>
290where
291 T: ops::AddAssign + Display + Serialize + DeserializeOwned,
292{
293 fn add_assign(&mut self, rhs: Generic<T>) {
294 *self += rhs.into_inner();
295 }
296}
297
298impl<T> ops::SubAssign<T> for Generic<T>
299where
300 T: ops::SubAssign + Display + Serialize + DeserializeOwned,
301{
302 fn sub_assign(&mut self, rhs: T) {
303 if let Some(ref mut v) = self.cache {
304 *v -= rhs;
305 } else {
306 self.cache = Some(rhs);
307 }
308
309 self.pushes_to_redis();
310 }
311}
312
313impl<T> ops::SubAssign<Generic<T>> for Generic<T>
314where
315 T: ops::SubAssign + Display + Serialize + DeserializeOwned,
316{
317 fn sub_assign(&mut self, rhs: Generic<T>) {
318 *self -= rhs.into_inner();
319 }
320}
321
322impl<T> ops::BitOr<T> for Generic<T>
323where
324 T: ops::BitOr<Output = T> + Display + Serialize + DeserializeOwned,
325{
326 type Output = Generic<T>;
327
328 fn bitor(self, rhs: T) -> Self::Output {
329 apply_operator(self, rhs, |a, b| a | b)
330 }
331}
332
333impl<T> ops::BitOr<Generic<T>> for Generic<T>
334where
335 T: ops::BitOr<Output = T> + Display + Serialize + DeserializeOwned,
336{
337 type Output = Generic<T>;
338
339 fn bitor(self, rhs: Generic<T>) -> Self::Output {
340 self | rhs.into_inner()
341 }
342}
343
344impl<T> ops::BitAnd<T> for Generic<T>
345where
346 T: ops::BitAnd<Output = T> + Display + Serialize + DeserializeOwned,
347{
348 type Output = Generic<T>;
349
350 fn bitand(self, rhs: T) -> Self::Output {
351 apply_operator(self, rhs, |a, b| a & b)
352 }
353}
354
355impl<T> ops::BitAnd<Generic<T>> for Generic<T>
356where
357 T: ops::BitAnd<Output = T> + Display + Serialize + DeserializeOwned,
358{
359 type Output = Generic<T>;
360
361 fn bitand(self, rhs: Generic<T>) -> Self::Output {
362 self & rhs.into_inner()
363 }
364}
365
366impl<T> ops::BitXor<T> for Generic<T>
367where
368 T: ops::BitXor<Output = T> + Display + Serialize + DeserializeOwned,
369{
370 type Output = Generic<T>;
371
372 fn bitxor(self, rhs: T) -> Self::Output {
373 apply_operator(self, rhs, |a, b| a ^ b)
374 }
375}
376
377impl<T> ops::BitXor<Generic<T>> for Generic<T>
378where
379 T: ops::BitXor<Output = T> + Display + Serialize + DeserializeOwned,
380{
381 type Output = Generic<T>;
382
383 fn bitxor(self, rhs: Generic<T>) -> Self::Output {
384 self ^ rhs.into_inner()
385 }
386}
387
388impl<T: PartialEq> PartialEq<T> for Generic<T> {
389 fn eq(&self, other: &T) -> bool {
390 self.cache.as_ref() == Some(other)
391 }
392}
393
394impl<T: PartialEq> PartialEq<Generic<T>> for Generic<T> {
395 fn eq(&self, other: &Generic<T>) -> bool {
396 self.cache == other.cache
397 }
398}
399
400impl<T: Debug> Debug for Generic<T> {
401 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
402 f.debug_struct("Generic")
403 .field("value", &self.cache)
404 .field("field_name", &self.key)
405 .finish()
406 }
407}
408
409#[cfg(test)]
410mod tests {
411 use super::*;
412 #[test]
413 fn test_partialeq() {
414 let s1 = Generic::with_value(
415 2,
416 "test_partialeq",
417 redis::Client::open("redis://localhost/").unwrap(),
418 );
419 assert_eq!(s1, 2);
420 }
421}