ruipay/
session.rs

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, // no value
38    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        // let encoded = serde_json::to_string(&self).unwrap_or_default();
56        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    /// Always less than zero.
86    NegInt(i64),
87    /// Always finite.
88    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                    // SIMPLE_STORAGE.remove(key);
371                    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        /// 在zsetname集合中增加序号为n的value
464        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        /// 排序指定的rank(排名)范围内的元素并输出
473        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        /// 反向排序
490        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        /// 获取指定的score范围内的元素
499        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        /// 获取a<=x<=b范围的数据,如果分页加上limit
508        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        /// 为score累加n,新元素score基数为0
517        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        /// 删除zsetname集合中指定的元素
526        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        /// 获取zsetname集合的元素个数
535        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        /// 删除下标在start end 范围内的元素
544        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        /// 命令判断成员元素是否是集合的成员
553        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        /// 成员元素添加到集合中
562        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        /// 删除score在[min [max 范围内的元素
571        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        /// 查询指定value的排名,注意不是score
588        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        /// 移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
789        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        /// 移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
798        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        /// 移出并获取列表的第一个元素
807        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        /// 通过索引获取列表中的元素
816        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        /// 获取列表长度
825        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        /// 获取列表指定范围内的元素
834        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        /// 在列表中添加一个或多个值
843        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        /// 在列表中添加一个或多个值
852        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    // let session = SimpleStorage::new();
909    // println!("000000");
910    // let s  = session.set("a", "n", Some(0)).unwrap();
911    // println!("1111");
912    // let v = session.get::<&str, String>("a", None).unwrap();
913    //
914    // println!("v:{}" , v.unwrap_or_default());
915}