1use std::{collections::BTreeMap, any::type_name, fmt, error};
2use dashmap::DashMap;
3use once_cell::sync::Lazy;
4
5use redis::{FromRedisValue, ToRedisArgs};
6use serde::{Deserialize, Serialize};
7use crate::{get_timestamp, LabradorResult};
8
9pub trait SessionStore: Clone {
10 fn get<'a, K: AsRef<str>, T: FromStore>(&self, key: K, default: Option<T>) -> LabradorResult<Option<T>>;
11 fn set<'a, K: AsRef<str>, T: ToStore>(&self, key: K, value: T, ttl: Option<usize>) -> LabradorResult<()>;
12}
13
14pub trait ToStore {
15 fn to_store(&self) -> Store;
16}
17
18pub trait FromStore: Sized {
19 fn from_store(v: &Store) -> Self {
20 match Self::from_store_opt(v) {
21 Ok(x) => x,
22 Err(_err) => panic!(
23 "Couldn't from {:?} to type {}. (see FromStore documentation)",
24 v,
25 type_name::<Self>(),
26 ),
27 }
28 }
29
30 fn from_store_opt(v: &Store) -> Result<Self, StoreError>;
31}
32
33
34#[derive(Serialize, Deserialize, Debug, Clone)]
35pub enum Store {
36 Json(serde_json::Value),
37 Null, Bool(bool),
39
40 Number(Number),
41
42 String(String),
43
44 Object(BTreeMap<String, Store>),
45
46 Array(Vec<Store>),
47}
48
49
50impl ToRedisArgs for Store {
51 fn write_redis_args<W>(&self, out: &mut W)
52 where
53 W: ?Sized + redis::RedisWrite {
54 let encoded: Vec<u8> = bincode::serialize(&self).unwrap_or_default();
55 out.write_arg(&encoded[..])
57 }
58}
59
60impl FromRedisValue for Store {
61 fn from_redis_value(v: &redis::Value) -> redis::RedisResult<Self> {
62 match *v {
63 redis::Value::Data(ref bytes) => {
64 let data = bincode::deserialize::<Store>(bytes).unwrap_or(Store::Null);
65 Ok(data)
66 },
67 redis::Value::Okay => Ok(Store::Null),
68 _ => Err(redis::RedisError::from((
69 redis::ErrorKind::TypeError,
70 "Response was of incompatible type",
71 format!("(response was {:?})", v),
72 ))),
73 }
74 }
75}
76
77#[derive(Clone, Eq, PartialEq, Deserialize, Serialize, Debug)]
78pub struct Number {
79 n: N,
80}
81
82#[derive(Copy, Clone, PartialEq, Deserialize, Serialize, Debug)]
83enum N {
84 PosInt(u64),
85 NegInt(i64),
87 Float(f64),
89}
90
91impl Eq for N {}
92
93#[allow(unused)]
94impl Number {
95 #[inline]
96 pub fn is_i64(&self) -> bool {
97 match self.n {
98 N::PosInt(v) => v <= i64::max_value() as u64,
99 N::NegInt(_) => true,
100 N::Float(_) => false,
101 }
102 }
103
104 #[inline]
105 pub fn is_u64(&self) -> bool {
106 match self.n {
107 N::PosInt(_) => true,
108 N::NegInt(_) | N::Float(_) => false,
109 }
110 }
111
112 #[inline]
113 pub fn is_f64(&self) -> bool {
114 match self.n {
115 N::Float(_) => true,
116 N::PosInt(_) | N::NegInt(_) => false,
117 }
118 }
119
120 #[inline]
121 pub fn as_i64(&self) -> Option<i64> {
122 match self.n {
123 N::PosInt(n) => {
124 if n <= i64::max_value() as u64 {
125 Some(n as i64)
126 } else {
127 None
128 }
129 }
130 N::NegInt(n) => Some(n),
131 N::Float(_) => None,
132 }
133 }
134
135 #[inline]
136 pub fn as_u64(&self) -> Option<u64> {
137 match self.n {
138 N::PosInt(n) => Some(n),
139 N::NegInt(_) | N::Float(_) => None,
140 }
141 }
142
143 #[inline]
144 pub fn as_f64(&self) -> Option<f64> {
145 match self.n {
146 N::PosInt(n) => Some(n as f64),
147 N::NegInt(n) => Some(n as f64),
148 N::Float(n) => Some(n),
149 }
150 }
151
152 #[inline]
153 pub fn from_f64(f: f64) -> Option<Number> {
154 if f.is_finite() {
155 let n = {
156 {
157 N::Float(f)
158 }
159 };
160 Some(Number { n })
161 } else {
162 None
163 }
164 }
165}
166
167
168macro_rules! impl_to_store {
169 ($ty:ty, $variant:ident) => {
170 impl ToStore for $ty {
171 fn to_store(&self) -> Store {
172 Store::$variant(self.to_owned())
173 }
174 }
175 };
176}
177
178
179macro_rules! impl_to_store_number {
180 ($ty:ty, $variant:ident, $t_ty:ty) => {
181 impl ToStore for $ty {
182 fn to_store(&self) -> Store {
183 let n = {
184 {
185 N::$variant(*self as $t_ty)
186 }
187 };
188 Store::Number(Number { n })
189 }
190 }
191 };
192}
193
194impl_to_store_number!(i32, NegInt, i64);
195impl_to_store_number!(f32, Float, f64);
196impl_to_store_number!(f64, Float, f64);
197impl_to_store_number!(i64, NegInt, i64);
198impl_to_store_number!(i128, NegInt, i64);
199impl_to_store_number!(u32, PosInt, u64);
200impl_to_store_number!(u64, PosInt, u64);
201impl_to_store_number!(u128, PosInt, u64);
202
203impl_to_store!(String, String);
204impl_to_store!(bool, Bool);
205impl_to_store!(BTreeMap<String, Store>, Object);
206impl_to_store!(serde_json::Value, Json);
207
208
209impl <T> ToStore for Vec<T>
210where T: ToStore {
211 fn to_store(&self) -> Store {
212 Store::Array(self.iter().map(T::to_store).collect())
213 }
214}
215
216impl <T> ToStore for &T
217where T: ToStore {
218 fn to_store(&self) -> Store {
219 T::to_store(&self)
220 }
221}
222impl ToStore for &str {
223 fn to_store(&self) -> Store {
224 Store::String(self.to_string())
225 }
226}
227
228impl <T> ToStore for Option<T>
229where T: ToStore {
230 fn to_store(&self) -> Store {
231 self.as_ref().map(|t| t.to_store()).unwrap_or(Store::Null)
232 }
233}
234
235impl ToStore for Store {
236 fn to_store(&self) -> Store {
237 self.to_owned()
238 }
239}
240
241macro_rules! impl_from_store_number {
242 ($ty: ty) => {
243 impl FromStore for $ty {
244 fn from_store_opt(v: &Store) -> Result<Self, StoreError> {
245 match v {
246 Store::Number(v) => {
247 Ok(match v.n {
248 N::PosInt(n) => n as $ty,
249 N::NegInt(n) => n as $ty,
250 N::Float(n) => n as $ty,
251 })
252 },
253 _ => Err(StoreError::NotSupported(format!("{:?}",v)))
254 }
255 }
256 }
257 }
258}
259
260impl_from_store_number!(u8);
261impl_from_store_number!(u16);
262impl_from_store_number!(u32);
263impl_from_store_number!(u64);
264impl_from_store_number!(i8);
265impl_from_store_number!(i16);
266impl_from_store_number!(i32);
267impl_from_store_number!(i64);
268impl_from_store_number!(isize);
269impl_from_store_number!(usize);
270impl_from_store_number!(f64);
271impl_from_store_number!(f32);
272
273macro_rules! impl_from_store {
274 ($ty:ty, $variant:ident) => {
275 impl FromStore for $ty {
276 fn from_store_opt(v: &Store) -> Result<Self, StoreError> {
277 match v {
278 Store::$variant(v) => Ok(v.to_owned()),
279 _ => Err(StoreError::NotSupported(format!("{:?}",v)))
280 }
281 }
282 }
283 };
284}
285
286impl_from_store!(String, String);
287impl_from_store!(bool, Bool);
288impl_from_store!(BTreeMap<String, Store>, Object);
289impl_from_store!(serde_json::Value, Json);
290
291impl <T> FromStore for Vec<T>
292where T: FromStore {
293 fn from_store_opt(v: &Store) -> Result<Self, StoreError> {
294 match v {
295 Store::Array(v) => Ok(v.iter().map(T::from_store).collect()),
296 _ => Err(StoreError::NotSupported(format!("{:?}",v)))
297 }
298 }
299}
300
301impl <T> FromStore for Option<T>
302where T: FromStore {
303 fn from_store_opt(v: &Store) -> Result<Self, StoreError> {
304 match *v {
305 Store::Null => Ok(None),
306 _ => FromStore::from_store_opt(v).map(Some),
307 }
308 }
309}
310
311impl FromStore for Store {
312 fn from_store_opt(v: &Store) -> Result<Self, StoreError> {
313 Ok(v.to_owned())
314 }
315}
316
317#[allow(unused)]
318#[derive(Debug)]
319pub enum StoreError {
320 NotSupported(String),
321 Unknown,
322}
323
324
325impl fmt::Display for StoreError {
326 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
327 match *self {
328 StoreError::NotSupported(ref err) => write!(f, "NotSupported Store Error message: {}", err),
329 StoreError::Unknown => write!(f, "Unknown Error"),
330 }
331 }
332}
333
334impl error::Error for StoreError {
335 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
336 None
337 }
338 fn description(&self) -> &str {
339 match self {
340 StoreError::NotSupported(ref err) => err,
341 StoreError::Unknown => "Unknown Error",
342 }
343 }
344}
345
346pub static SIMPLE_STORAGE: Lazy<DashMap<String, (Option<usize>, Store)>> = Lazy::new(|| {
347 DashMap::new()
348});
349
350#[derive(Debug, Clone)]
351pub struct SimpleStorage {
352}
353
354impl SimpleStorage {
355 pub fn new() -> SimpleStorage {
356 SimpleStorage { }
357 }
358}
359
360impl SessionStore for SimpleStorage {
361 fn get<'a, K: AsRef<str>, T: FromStore>(&self, key: K, default: Option<T>) -> LabradorResult<Option<T>> {
362 let mut is_expire = false;
363 let key = key.as_ref();
364 let v = if let Some(v) = SIMPLE_STORAGE.get(&key.to_string()) {
365 let (ttl, value) = v.value();
366 if let Some(ttl) = ttl {
367 let current_stamp = get_timestamp() as usize;
368 let exipre_at = current_stamp + *ttl;
369 if current_stamp >= exipre_at {
370 is_expire = true;
372 None
373 } else {
374 Some(T::from_store(&value))
375 }
376 } else {
377 Some(T::from_store(&value))
378 }
379 } else {
380 default
381 };
382 if is_expire {
383 SIMPLE_STORAGE.remove(key);
384 }
385 Ok(v)
386 }
387
388 fn set<'a, K: AsRef<str>, T: ToStore>(&self, key: K, value: T, ttl: Option<usize>) -> LabradorResult<()> {
389 let key = key.as_ref();
390 let ttl = if let Some(ttl) = ttl {
391 Some(ttl)
392 } else {
393 None
394 };
395 SIMPLE_STORAGE.insert(key.to_string(), (ttl, T::to_store(&value)));
396 Ok(())
397 }
398}
399
400
401pub mod redis_store {
402
403 pub type RedisPool = Pool<redis::Client>;
404 use r2d2::{Pool};
405 use redis::{self, ToRedisArgs, ConnectionLike, Commands, FromRedisValue, streams};
406 use crate::{LabradorResult, LabraError};
407
408 use super::{SessionStore, ToStore, FromStore, Store};
409
410 #[derive(Debug, Clone)]
411 pub struct RedisStorage {
412 client_pool: RedisPool
413 }
414
415
416 #[allow(unused)]
417 impl RedisStorage {
418 pub fn new(client: redis::Client) -> RedisStorage {
419 let pool = Pool::builder().max_size(4).build(client).expect("can not get the redis client");
420 RedisStorage {
421 client_pool: pool,
422 }
423 }
424
425 pub fn from_pool(client: Pool<redis::Client>) -> RedisStorage {
426 RedisStorage {
427 client_pool: client,
428 }
429 }
430
431 pub fn from_url<U: AsRef<str>>(url: U) -> RedisStorage {
432 let client = redis::Client::open(url.as_ref()).expect("can not get the redis pool");
433 let pool = Pool::builder().max_size(4).build(client).expect("can not get the redis pool");
434 RedisStorage {
435 client_pool: pool,
436 }
437 }
438
439 fn get_connect(&self) -> RedisPool {
440 let pool = self.client_pool.to_owned();
441 pool
442 }
443
444
445
446 pub fn del<K: AsRef<str>>(&self, key: K) -> LabradorResult<()> {
447 let mut client = self.client_pool.get()?;
448 if !client.check_connection() {
449 return Err(LabraError::ApiError("error to get redis connection".to_string()))
450 }
451 let s = client.del(key.as_ref())?;
452 Ok(())
453 }
454
455 pub fn zlcount<K: AsRef<str>, M: ToRedisArgs, MM: ToRedisArgs, RV: FromRedisValue>(&self, key: K, min: M, max: MM) -> LabradorResult<RV> {
456 let mut client = self.client_pool.get()?;
457 if !client.check_connection() {
458 return Err(LabraError::ApiError("error to get redis connection".to_string()))
459 }
460 client.zcount(key.as_ref(), min, max).map_err(LabraError::from)
461 }
462
463 pub fn zadd<K: AsRef<str>, S: ToRedisArgs, M: ToRedisArgs, RV: FromRedisValue>(&self, key: K, member: M, score: S) -> LabradorResult<RV> {
465 let mut client = self.client_pool.get()?;
466 if !client.check_connection() {
467 return Err(LabraError::ApiError("error to get redis connection".to_string()))
468 }
469 client.zadd(key.as_ref(), member, score).map_err(LabraError::from)
470 }
471
472 pub fn zrange<K: AsRef<str>, RV: FromRedisValue>(&self, key: K, start: isize, stop: isize) -> LabradorResult<RV> {
474 let mut client = self.client_pool.get()?;
475 if !client.check_connection() {
476 return Err(LabraError::ApiError("error to get redis connection".to_string()))
477 }
478 client.zrange(key.as_ref(), start, stop).map_err(LabraError::from)
479 }
480
481 pub fn zadd_multiple<K: AsRef<str>, S: ToRedisArgs, M: ToRedisArgs, RV: FromRedisValue>(&self, key: K, items: &[(S, M)]) -> LabradorResult<RV> {
482 let mut client = self.client_pool.get()?;
483 if !client.check_connection() {
484 return Err(LabraError::ApiError("error to get redis connection".to_string()))
485 }
486 client.zadd_multiple(key.as_ref(), items).map_err(LabraError::from)
487 }
488
489 pub fn zrevrange<K: AsRef<str>, RV: FromRedisValue>(&self, key: K, start: isize, stop: isize) -> LabradorResult<RV> {
491 let mut client = self.client_pool.get()?;
492 if !client.check_connection() {
493 return Err(LabraError::ApiError("error to get redis connection".to_string()))
494 }
495 client.zrevrange(key.as_ref(), start, stop).map_err(LabraError::from)
496 }
497
498 pub fn zrangebyscore<K: AsRef<str>, M: ToRedisArgs, MM: ToRedisArgs, RV: FromRedisValue>(&self, key: K, min: M, max: MM) -> LabradorResult<RV> {
500 let mut client = self.client_pool.get()?;
501 if !client.check_connection() {
502 return Err(LabraError::ApiError("error to get redis connection".to_string()))
503 }
504 client.zrangebyscore(key.as_ref(), min, max).map_err(LabraError::from)
505 }
506
507 pub fn zrangebylex<K: AsRef<str>, M: ToRedisArgs, MM: ToRedisArgs, RV: FromRedisValue>(&self, key: K, min: M, max: MM) -> LabradorResult<RV> {
509 let mut client = self.client_pool.get()?;
510 if !client.check_connection() {
511 return Err(LabraError::ApiError("error to get redis connection".to_string()))
512 }
513 client.zrangebylex(key.as_ref(), min, max).map_err(LabraError::from)
514 }
515
516 pub fn zincr<K: AsRef<str>, M: ToRedisArgs, D: ToRedisArgs, RV: FromRedisValue>(&self, key: K, member: M, delta: D) -> LabradorResult<RV> {
518 let mut client = self.client_pool.get()?;
519 if !client.check_connection() {
520 return Err(LabraError::ApiError("error to get redis connection".to_string()))
521 }
522 client.zincr(key.as_ref(), member, delta).map_err(LabraError::from)
523 }
524
525 pub fn zrem<K: AsRef<str>, M: ToRedisArgs, RV: FromRedisValue>(&self, key: K, members: M) -> LabradorResult<RV> {
527 let mut client = self.client_pool.get()?;
528 if !client.check_connection() {
529 return Err(LabraError::ApiError("error to get redis connection".to_string()))
530 }
531 client.zrem(key.as_ref(), members).map_err(LabraError::from)
532 }
533
534 pub fn zcard<K: AsRef<str>, RV: FromRedisValue>(&self, key: K) -> LabradorResult<RV> {
536 let mut client = self.client_pool.get()?;
537 if !client.check_connection() {
538 return Err(LabraError::ApiError("error to get redis connection".to_string()))
539 }
540 client.zcard(key.as_ref()).map_err(LabraError::from)
541 }
542
543 pub fn zremrangebyrank<K: AsRef<str>, RV: FromRedisValue>(&self, key: K, start: isize, stop: isize) -> LabradorResult<RV> {
545 let mut client = self.client_pool.get()?;
546 if !client.check_connection() {
547 return Err(LabraError::ApiError("error to get redis connection".to_string()))
548 }
549 client.zremrangebyrank(key.as_ref(), start, stop).map_err(LabraError::from)
550 }
551
552 pub fn sismember<K: AsRef<str>,M: ToRedisArgs, RV: FromRedisValue>(&self, key: K, member: M) -> LabradorResult<RV> {
554 let mut client = self.client_pool.get()?;
555 if !client.check_connection() {
556 return Err(LabraError::ApiError("error to get redis connection".to_string()))
557 }
558 client.sismember(key.as_ref(), member).map_err(LabraError::from)
559 }
560
561 pub fn sadd<K: AsRef<str>,M: ToRedisArgs, RV: FromRedisValue>(&self, key: K, member: M) -> LabradorResult<RV> {
563 let mut client = self.client_pool.get()?;
564 if !client.check_connection() {
565 return Err(LabraError::ApiError("error to get redis connection".to_string()))
566 }
567 client.sadd(key.as_ref(), member).map_err(LabraError::from)
568 }
569
570 pub fn zrembyscore<K: AsRef<str>, M: ToRedisArgs, MM: ToRedisArgs, RV: FromRedisValue>(&self, key: K, min: M, max: MM) -> LabradorResult<RV> {
572 let mut client = self.client_pool.get()?;
573 if !client.check_connection() {
574 return Err(LabraError::ApiError("error to get redis connection".to_string()))
575 }
576 client.zrembyscore(key.as_ref(), min, max).map_err(LabraError::from)
577 }
578
579 pub fn zrembylex<K: AsRef<str>, M: ToRedisArgs, MM: ToRedisArgs, RV: FromRedisValue>(&self, key: K, min: M, max: MM) -> LabradorResult<RV> {
580 let mut client = self.client_pool.get()?;
581 if !client.check_connection() {
582 return Err(LabraError::ApiError("error to get redis connection".to_string()))
583 }
584 client.zrembylex(key.as_ref(), min, max).map_err(LabraError::from)
585 }
586
587 pub fn zrank<K: AsRef<str>, M: ToRedisArgs, RV: FromRedisValue>(&self, key: K, member: M) -> LabradorResult<RV> {
589 let mut client = self.client_pool.get()?;
590 if !client.check_connection() {
591 return Err(LabraError::ApiError("error to get redis connection".to_string()))
592 }
593 client.zrank(key.as_ref(), member).map_err(LabraError::from)
594 }
595
596 pub fn xadd<K: AsRef<str>, F: ToRedisArgs, V: ToRedisArgs, RV: FromRedisValue>(&self, key: K, items: &[(F, V)]) -> LabradorResult<RV> {
597 let mut client = self.client_pool.get()?;
598 if !client.check_connection() {
599 return Err(LabraError::ApiError("error to get redis connection".to_string()))
600 }
601 client.xadd(key.as_ref(), "*", items).map_err(LabraError::from)
602 }
603
604 pub fn xadd_map<K: AsRef<str>, BTM: ToRedisArgs, RV: FromRedisValue>(&self, key: K, items: BTM) -> LabradorResult<RV> {
605 let mut client = self.client_pool.get()?;
606 if !client.check_connection() {
607 return Err(LabraError::ApiError("error to get redis connection".to_string()))
608 }
609 client.xadd_map(key.as_ref(), "*", items).map_err(LabraError::from)
610 }
611
612 pub fn xread<'a, K: ToRedisArgs, ID: ToRedisArgs, RV: FromRedisValue>(&self, keys: &'a [K], ids: &'a [ID]) -> LabradorResult<RV> {
613 let mut client = self.client_pool.get()?;
614 if !client.check_connection() {
615 return Err(LabraError::ApiError("error to get redis connection".to_string()))
616 }
617 client.xread(keys, ids).map_err(LabraError::from)
618 }
619
620 pub fn xinfo_consumers<'a, K: ToRedisArgs, G: ToRedisArgs, RV: FromRedisValue>(&self, key: K, group: G) -> LabradorResult<RV> {
621 let mut client = self.client_pool.get()?;
622 if !client.check_connection() {
623 return Err(LabraError::ApiError("error to get redis connection".to_string()))
624 }
625 client.xinfo_consumers(key, group).map_err(LabraError::from)
626 }
627
628 pub fn xinfo_groups<'a, K: ToRedisArgs, RV: FromRedisValue>(&self, key: K) -> LabradorResult<RV> {
629 let mut client = self.client_pool.get()?;
630 if !client.check_connection() {
631 return Err(LabraError::ApiError("error to get redis connection".to_string()))
632 }
633 client.xinfo_groups(key).map_err(LabraError::from)
634 }
635
636 pub fn xinfo_stream<'a, K: ToRedisArgs, RV: FromRedisValue>(&self, key: K) -> LabradorResult<RV> {
637 let mut client = self.client_pool.get()?;
638 if !client.check_connection() {
639 return Err(LabraError::ApiError("error to get redis connection".to_string()))
640 }
641 client.xinfo_stream(key).map_err(LabraError::from)
642 }
643
644 pub fn xread_options<'a, K: ToRedisArgs, ID: ToRedisArgs, RV: FromRedisValue>(&self, keys: &'a [K], ids: &'a [ID], options: &'a streams::StreamReadOptions) -> LabradorResult<RV> {
645 let mut client = self.client_pool.get()?;
646 if !client.check_connection() {
647 return Err(LabraError::ApiError("error to get redis connection".to_string()))
648 }
649 client.xread_options(keys, ids, options).map_err(LabraError::from)
650 }
651
652 pub fn xgroup_create<'a, K: ToRedisArgs, G: ToRedisArgs, ID: ToRedisArgs, RV: FromRedisValue>(&self, key: K, group: G, id: ID) -> LabradorResult<RV> {
653 let mut client = self.client_pool.get()?;
654 if !client.check_connection() {
655 return Err(LabraError::ApiError("error to get redis connection".to_string()))
656 }
657 client.xgroup_create(key, group, id).map_err(LabraError::from)
658 }
659
660 pub fn xgroup_delconsumer<'a, K: ToRedisArgs, G: ToRedisArgs, C: ToRedisArgs, RV: FromRedisValue>(&self, key: K, group: G, consumer: C) -> LabradorResult<RV> {
661 let mut client = self.client_pool.get()?;
662 if !client.check_connection() {
663 return Err(LabraError::ApiError("error to get redis connection".to_string()))
664 }
665 client.xgroup_delconsumer(key, group, consumer).map_err(LabraError::from)
666 }
667
668 pub fn xack<'a, K: ToRedisArgs, G: ToRedisArgs, I: ToRedisArgs, RV: FromRedisValue>(&self, key: K, group: G, ids: &'a [I]) -> LabradorResult<RV> {
669 let mut client = self.client_pool.get()?;
670 if !client.check_connection() {
671 return Err(LabraError::ApiError("error to get redis connection".to_string()))
672 }
673 client.xack(key, group, ids).map_err(LabraError::from)
674 }
675
676 pub fn xgroup_create_mkstream<'a, K: ToRedisArgs, G: ToRedisArgs, ID: ToRedisArgs, RV: FromRedisValue>(&self, key: K, group: G, id: ID) -> LabradorResult<RV> {
677 let mut client = self.client_pool.get()?;
678 if !client.check_connection() {
679 return Err(LabraError::ApiError("error to get redis connection".to_string()))
680 }
681 client.xgroup_create_mkstream(key, group, id).map_err(LabraError::from)
682 }
683
684 pub fn xgroup_destroy<'a, K: ToRedisArgs, G: ToRedisArgs, RV: FromRedisValue>(&self, key: K, group: G) -> LabradorResult<RV> {
685 let mut client = self.client_pool.get()?;
686 if !client.check_connection() {
687 return Err(LabraError::ApiError("error to get redis connection".to_string()))
688 }
689 client.xgroup_destroy(key, group).map_err(LabraError::from)
690 }
691
692 pub fn xdel<'a, K: ToRedisArgs, ID: ToRedisArgs, RV: FromRedisValue>(&self, key: K, ids: &'a [ID]) -> LabradorResult<RV> {
693 let mut client = self.client_pool.get()?;
694 if !client.check_connection() {
695 return Err(LabraError::ApiError("error to get redis connection".to_string()))
696 }
697 client.xdel(key, ids).map_err(LabraError::from)
698 }
699
700 pub fn xpending<'a, K: ToRedisArgs, G: ToRedisArgs, RV: FromRedisValue>(&self, key: K, group: G) -> LabradorResult<RV> {
701 let mut client = self.client_pool.get()?;
702 if !client.check_connection() {
703 return Err(LabraError::ApiError("error to get redis connection".to_string()))
704 }
705 client.xpending(key, group).map_err(LabraError::from)
706 }
707
708 pub fn xpending_count<'a, K: ToRedisArgs, G: ToRedisArgs, S: ToRedisArgs, E: ToRedisArgs, C: ToRedisArgs, RV: FromRedisValue>(&self, key: K, group: G, start: S, end: E, count: C) -> LabradorResult<RV> {
709 let mut client = self.client_pool.get()?;
710 if !client.check_connection() {
711 return Err(LabraError::ApiError("error to get redis connection".to_string()))
712 }
713 client.xpending_count(key, group, start, end, count).map_err(LabraError::from)
714 }
715
716 pub fn xpending_consumer_count<'a, K: ToRedisArgs, G: ToRedisArgs, S: ToRedisArgs, E: ToRedisArgs, C: ToRedisArgs, CN: ToRedisArgs, RV: FromRedisValue>(&self, key: K, group: G, start: S, end: E, count: C, consumer: CN) -> LabradorResult<RV> {
717 let mut client = self.client_pool.get()?;
718 if !client.check_connection() {
719 return Err(LabraError::ApiError("error to get redis connection".to_string()))
720 }
721 client.xpending_consumer_count(key, group, start, end, count, consumer).map_err(LabraError::from)
722 }
723
724 pub fn xrevrange<'a, K: ToRedisArgs, E: ToRedisArgs, S: ToRedisArgs, RV: FromRedisValue>(&self, key: K, start: S, end: E) -> LabradorResult<RV> {
725 let mut client = self.client_pool.get()?;
726 if !client.check_connection() {
727 return Err(LabraError::ApiError("error to get redis connection".to_string()))
728 }
729 client.xrevrange(key, end, start).map_err(LabraError::from)
730 }
731
732 pub fn xrevrange_all<'a, K: ToRedisArgs, RV: FromRedisValue>(&self, key: K) -> LabradorResult<RV> {
733 let mut client = self.client_pool.get()?;
734 if !client.check_connection() {
735 return Err(LabraError::ApiError("error to get redis connection".to_string()))
736 }
737 client.xrevrange_all(key).map_err(LabraError::from)
738 }
739
740 pub fn xrevrange_count<'a, K: ToRedisArgs, E: ToRedisArgs, S: ToRedisArgs, C: ToRedisArgs,RV: FromRedisValue>(&self, key: K, start: S, end: E, count: C) -> LabradorResult<RV> {
741 let mut client = self.client_pool.get()?;
742 if !client.check_connection() {
743 return Err(LabraError::ApiError("error to get redis connection".to_string()))
744 }
745 client.xrevrange_count(key, end, start, count).map_err(LabraError::from)
746 }
747
748 pub fn exists<'a, K: ToRedisArgs,RV: FromRedisValue>(&self, key: K) -> LabradorResult<RV> {
749 let mut client = self.client_pool.get()?;
750 if !client.check_connection() {
751 return Err(LabraError::ApiError("error to get redis connection".to_string()))
752 }
753 client.exists(key).map_err(LabraError::from)
754 }
755
756 pub fn expire<'a, K: ToRedisArgs,RV: FromRedisValue>(&self, key: K, seconds: usize) -> LabradorResult<RV> {
757 let mut client = self.client_pool.get()?;
758 if !client.check_connection() {
759 return Err(LabraError::ApiError("error to get redis connection".to_string()))
760 }
761 client.expire(key, seconds).map_err(LabraError::from)
762 }
763
764 pub fn expire_at<'a, K: ToRedisArgs,RV: FromRedisValue>(&self, key: K, ts: usize) -> LabradorResult<RV> {
765 let mut client = self.client_pool.get()?;
766 if !client.check_connection() {
767 return Err(LabraError::ApiError("error to get redis connection".to_string()))
768 }
769 client.expire_at(key, ts).map_err(LabraError::from)
770 }
771
772 pub fn lpush<'a, K: ToRedisArgs, V: ToRedisArgs, RV: FromRedisValue>(&self, key: K, value: V) -> LabradorResult<RV> {
773 let mut client = self.client_pool.get()?;
774 if !client.check_connection() {
775 return Err(LabraError::ApiError("error to get redis connection".to_string()))
776 }
777 client.lpush(key, value).map_err(LabraError::from)
778 }
779
780 pub fn lpush_exists<'a, K: ToRedisArgs, V: ToRedisArgs, RV: FromRedisValue>(&self, key: K, value: V) -> LabradorResult<RV> {
781 let mut client = self.client_pool.get()?;
782 if !client.check_connection() {
783 return Err(LabraError::ApiError("error to get redis connection".to_string()))
784 }
785 client.lpush_exists(key, value).map_err(LabraError::from)
786 }
787
788 pub fn blpop<'a, K: ToRedisArgs, RV: FromRedisValue>(&self, key: K, timeout: usize) -> LabradorResult<RV> {
790 let mut client = self.client_pool.get()?;
791 if !client.check_connection() {
792 return Err(LabraError::ApiError("error to get redis connection".to_string()))
793 }
794 client.blpop(key, timeout).map_err(LabraError::from)
795 }
796
797 pub fn brpop<'a, K: ToRedisArgs, RV: FromRedisValue>(&self, key: K, timeout: usize) -> LabradorResult<RV> {
799 let mut client = self.client_pool.get()?;
800 if !client.check_connection() {
801 return Err(LabraError::ApiError("error to get redis connection".to_string()))
802 }
803 client.brpop(key, timeout).map_err(LabraError::from)
804 }
805
806 pub fn lpop<'a, K: ToRedisArgs, RV: FromRedisValue>(&self, key: K, count: Option<core::num::NonZeroUsize>) -> LabradorResult<RV> {
808 let mut client = self.client_pool.get()?;
809 if !client.check_connection() {
810 return Err(LabraError::ApiError("error to get redis connection".to_string()))
811 }
812 client.lpop(key, count).map_err(LabraError::from)
813 }
814
815 pub fn lindex<'a, K: ToRedisArgs, RV: FromRedisValue>(&self, key: K, index: isize) -> LabradorResult<RV> {
817 let mut client = self.client_pool.get()?;
818 if !client.check_connection() {
819 return Err(LabraError::ApiError("error to get redis connection".to_string()))
820 }
821 client.lindex(key, index).map_err(LabraError::from)
822 }
823
824 pub fn llen<'a, K: ToRedisArgs, RV: FromRedisValue>(&self, key: K) -> LabradorResult<RV> {
826 let mut client = self.client_pool.get()?;
827 if !client.check_connection() {
828 return Err(LabraError::ApiError("error to get redis connection".to_string()))
829 }
830 client.llen(key).map_err(LabraError::from)
831 }
832
833 pub fn lrange<'a, K: ToRedisArgs, RV: FromRedisValue>(&self, key: K, start: isize, stop: isize) -> LabradorResult<RV> {
835 let mut client = self.client_pool.get()?;
836 if !client.check_connection() {
837 return Err(LabraError::ApiError("error to get redis connection".to_string()))
838 }
839 client.lrange(key, start, stop).map_err(LabraError::from)
840 }
841
842 pub fn rpush<'a, K: ToRedisArgs, V: ToRedisArgs, RV: FromRedisValue>(&self, key: K, value: V) -> LabradorResult<RV> {
844 let mut client = self.client_pool.get()?;
845 if !client.check_connection() {
846 return Err(LabraError::ApiError("error to get redis connection".to_string()))
847 }
848 client.rpush(key, value).map_err(LabraError::from)
849 }
850
851 pub fn rpush_exists<'a, K: ToRedisArgs, V: ToRedisArgs, RV: FromRedisValue>(&self, key: K, value: V) -> LabradorResult<RV> {
853 let mut client = self.client_pool.get()?;
854 if !client.check_connection() {
855 return Err(LabraError::ApiError("error to get redis connection".to_string()))
856 }
857 client.rpush_exists(key, value).map_err(LabraError::from)
858 }
859 }
860
861
862 impl SessionStore for RedisStorage {
863
864 fn get<'a, K: AsRef<str>, T: FromStore>(&self, key: K, default: Option<T>) -> LabradorResult<Option<T>> {
865 let mut client = self.client_pool.get()?;
866 if !client.check_connection() {
867 return Err(LabraError::ApiError("error to get redis connection".to_string()))
868 }
869 let data = client.get::<_, Store>(key.as_ref());
870 if data.is_err() {
871 return Ok(default);
872 }
873 let v = if let Ok(value) = data {
874 match T::from_store_opt(&value) {
875 Ok(store) =>Some(store),
876 Err(_err) => None
877 }
878 } else {
879 default
880 };
881 Ok(v)
882 }
883
884 fn set<'a, K: AsRef<str>, T: ToStore>(&self, key: K, value: T, ttl: Option<usize>) -> LabradorResult<()> {
885 let mut client = self.client_pool.get()?;
886 let key = key.as_ref();
887 if !client.check_connection() {
888 return Err(LabraError::ApiError("error to get redis connection".to_string()))
889 }
890 if let Some(seconds) = ttl {
891 let _ = client.set_ex(key, value.to_store(), seconds)?;
892 } else {
893 let _ = client.set(key, value.to_store())?;
894 }
895
896 Ok(())
897 }
898 }
899}
900
901
902#[test]
903fn test_simple() {
904 println!("ssssssss");
905 let encoded: Vec<u8> = bincode::serialize(&Store::String("234".to_string())).unwrap();
906 let decode = bincode::deserialize::<Store>(&encoded).unwrap();
907 println!("decode:{:?}", decode);
908 }