1use crate::errors::ParsingError;
2#[cfg(feature = "ahash")]
3pub(crate) use ahash::{AHashMap as HashMap, AHashSet as HashSet};
4#[cfg(feature = "num-bigint")]
5use num_bigint::BigInt;
6use std::borrow::Cow;
7#[cfg(not(feature = "ahash"))]
8pub(crate) use std::collections::{HashMap, HashSet};
9use std::default::Default;
10use std::ffi::CString;
11use std::fmt;
12use std::hash::{BuildHasher, Hash};
13use std::io;
14use std::ops::Deref;
15use std::str::from_utf8;
16
17use crate::errors::{RedisError, ServerError};
18
19#[non_exhaustive]
21pub enum Expiry {
22 EX(u64),
24 PX(u64),
26 EXAT(u64),
28 PXAT(u64),
30 PERSIST,
32}
33
34#[derive(Clone, Copy)]
36#[non_exhaustive]
37pub enum SetExpiry {
38 EX(u64),
40 PX(u64),
42 EXAT(u64),
44 PXAT(u64),
46 KEEPTTL,
48}
49
50impl ToRedisArgs for SetExpiry {
51 fn write_redis_args<W>(&self, out: &mut W)
52 where
53 W: ?Sized + RedisWrite,
54 {
55 match self {
56 SetExpiry::EX(secs) => {
57 out.write_arg(b"EX");
58 out.write_arg(format!("{secs}").as_bytes());
59 }
60 SetExpiry::PX(millis) => {
61 out.write_arg(b"PX");
62 out.write_arg(format!("{millis}").as_bytes());
63 }
64 SetExpiry::EXAT(unix_time) => {
65 out.write_arg(b"EXAT");
66 out.write_arg(format!("{unix_time}").as_bytes());
67 }
68 SetExpiry::PXAT(unix_time) => {
69 out.write_arg(b"PXAT");
70 out.write_arg(format!("{unix_time}").as_bytes());
71 }
72 SetExpiry::KEEPTTL => {
73 out.write_arg(b"KEEPTTL");
74 }
75 }
76 }
77}
78
79#[derive(Clone, Copy)]
81#[non_exhaustive]
82pub enum ExistenceCheck {
83 NX,
85 XX,
87}
88
89impl ToRedisArgs for ExistenceCheck {
90 fn write_redis_args<W>(&self, out: &mut W)
91 where
92 W: ?Sized + RedisWrite,
93 {
94 match self {
95 ExistenceCheck::NX => {
96 out.write_arg(b"NX");
97 }
98 ExistenceCheck::XX => {
99 out.write_arg(b"XX");
100 }
101 }
102 }
103}
104
105#[derive(Clone, Copy)]
107#[non_exhaustive]
108pub enum FieldExistenceCheck {
109 FNX,
111 FXX,
113}
114
115impl ToRedisArgs for FieldExistenceCheck {
116 fn write_redis_args<W>(&self, out: &mut W)
117 where
118 W: ?Sized + RedisWrite,
119 {
120 match self {
121 FieldExistenceCheck::FNX => out.write_arg(b"FNX"),
122 FieldExistenceCheck::FXX => out.write_arg(b"FXX"),
123 }
124 }
125}
126
127#[derive(PartialEq, Eq, Clone, Debug, Copy)]
130#[non_exhaustive]
131pub enum NumericBehavior {
132 NonNumeric,
134 NumberIsInteger,
136 NumberIsFloat,
138}
139
140#[derive(PartialEq, Clone, Default)]
142#[non_exhaustive]
143pub enum Value {
144 #[default]
146 Nil,
147 Int(i64),
152 BulkString(Vec<u8>),
154 Array(Vec<Value>),
157 SimpleString(String),
159 Okay,
161 Map(Vec<(Value, Value)>),
163 Attribute {
165 data: Box<Value>,
167 attributes: Vec<(Value, Value)>,
169 },
170 Set(Vec<Value>),
172 Double(f64),
174 Boolean(bool),
176 VerbatimString {
178 format: VerbatimFormat,
180 text: String,
182 },
183 #[cfg(feature = "num-bigint")]
184 BigNumber(BigInt),
186 #[cfg(not(feature = "num-bigint"))]
187 BigNumber(Vec<u8>),
189 Push {
191 kind: PushKind,
193 data: Vec<Value>,
195 },
196 ServerError(ServerError),
198}
199
200#[derive(Clone, Debug)]
213#[non_exhaustive]
214pub enum ValueComparison {
215 IFEQ(String),
217 IFNE(String),
219 IFDEQ(String),
221 IFDNE(String),
223}
224
225impl ValueComparison {
226 pub fn ifeq(value: impl ToSingleRedisArg) -> Self {
233 ValueComparison::IFEQ(Self::arg_to_string(value))
234 }
235
236 pub fn ifne(value: impl ToSingleRedisArg) -> Self {
243 ValueComparison::IFNE(Self::arg_to_string(value))
244 }
245
246 pub fn ifdeq(digest: impl ToSingleRedisArg) -> Self {
255 ValueComparison::IFDEQ(Self::arg_to_string(digest))
256 }
257
258 pub fn ifdne(digest: impl ToSingleRedisArg) -> Self {
267 ValueComparison::IFDNE(Self::arg_to_string(digest))
268 }
269
270 fn arg_to_string(value: impl ToSingleRedisArg) -> String {
271 let args = value.to_redis_args();
272 String::from_utf8_lossy(&args[0]).into_owned()
273 }
274}
275
276impl ToRedisArgs for ValueComparison {
277 fn write_redis_args<W>(&self, out: &mut W)
278 where
279 W: ?Sized + RedisWrite,
280 {
281 match self {
282 ValueComparison::IFEQ(value) => {
283 out.write_arg(b"IFEQ");
284 out.write_arg(value.as_bytes());
285 }
286 ValueComparison::IFNE(value) => {
287 out.write_arg(b"IFNE");
288 out.write_arg(value.as_bytes());
289 }
290 ValueComparison::IFDEQ(digest) => {
291 out.write_arg(b"IFDEQ");
292 out.write_arg(digest.as_bytes());
293 }
294 ValueComparison::IFDNE(digest) => {
295 out.write_arg(b"IFDNE");
296 out.write_arg(digest.as_bytes());
297 }
298 }
299 }
300}
301
302#[derive(PartialEq, Clone, Debug)]
304#[non_exhaustive]
305pub enum VerbatimFormat {
306 Unknown(String),
308 Markdown,
310 Text,
312}
313
314#[derive(PartialEq, Clone, Debug)]
316#[non_exhaustive]
317pub enum PushKind {
318 Disconnection,
320 Other(String),
322 Invalidate,
324 Message,
326 PMessage,
328 SMessage,
330 Unsubscribe,
332 PUnsubscribe,
334 SUnsubscribe,
336 Subscribe,
338 PSubscribe,
340 SSubscribe,
342}
343
344impl PushKind {
345 #[cfg(feature = "aio")]
346 pub(crate) fn has_reply(&self) -> bool {
347 matches!(
348 self,
349 &PushKind::Unsubscribe
350 | &PushKind::PUnsubscribe
351 | &PushKind::SUnsubscribe
352 | &PushKind::Subscribe
353 | &PushKind::PSubscribe
354 | &PushKind::SSubscribe
355 )
356 }
357}
358
359impl fmt::Display for VerbatimFormat {
360 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
361 match self {
362 VerbatimFormat::Markdown => write!(f, "mkd"),
363 VerbatimFormat::Unknown(val) => write!(f, "{val}"),
364 VerbatimFormat::Text => write!(f, "txt"),
365 }
366 }
367}
368
369impl fmt::Display for PushKind {
370 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
371 match self {
372 PushKind::Other(kind) => write!(f, "{kind}"),
373 PushKind::Invalidate => write!(f, "invalidate"),
374 PushKind::Message => write!(f, "message"),
375 PushKind::PMessage => write!(f, "pmessage"),
376 PushKind::SMessage => write!(f, "smessage"),
377 PushKind::Unsubscribe => write!(f, "unsubscribe"),
378 PushKind::PUnsubscribe => write!(f, "punsubscribe"),
379 PushKind::SUnsubscribe => write!(f, "sunsubscribe"),
380 PushKind::Subscribe => write!(f, "subscribe"),
381 PushKind::PSubscribe => write!(f, "psubscribe"),
382 PushKind::SSubscribe => write!(f, "ssubscribe"),
383 PushKind::Disconnection => write!(f, "disconnection"),
384 }
385 }
386}
387
388#[non_exhaustive]
389pub enum MapIter<'a> {
390 Array(std::slice::Iter<'a, Value>),
391 Map(std::slice::Iter<'a, (Value, Value)>),
392}
393
394impl<'a> Iterator for MapIter<'a> {
395 type Item = (&'a Value, &'a Value);
396
397 fn next(&mut self) -> Option<Self::Item> {
398 match self {
399 MapIter::Array(iter) => Some((iter.next()?, iter.next()?)),
400 MapIter::Map(iter) => {
401 let (k, v) = iter.next()?;
402 Some((k, v))
403 }
404 }
405 }
406
407 fn size_hint(&self) -> (usize, Option<usize>) {
408 match self {
409 MapIter::Array(iter) => iter.size_hint(),
410 MapIter::Map(iter) => iter.size_hint(),
411 }
412 }
413}
414
415#[non_exhaustive]
416pub enum OwnedMapIter {
417 Array(std::vec::IntoIter<Value>),
418 Map(std::vec::IntoIter<(Value, Value)>),
419}
420
421impl Iterator for OwnedMapIter {
422 type Item = (Value, Value);
423
424 fn next(&mut self) -> Option<Self::Item> {
425 match self {
426 OwnedMapIter::Array(iter) => Some((iter.next()?, iter.next()?)),
427 OwnedMapIter::Map(iter) => iter.next(),
428 }
429 }
430
431 fn size_hint(&self) -> (usize, Option<usize>) {
432 match self {
433 OwnedMapIter::Array(iter) => {
434 let (low, high) = iter.size_hint();
435 (low / 2, high.map(|h| h / 2))
436 }
437 OwnedMapIter::Map(iter) => iter.size_hint(),
438 }
439 }
440}
441
442impl Value {
450 pub fn looks_like_cursor(&self) -> bool {
455 match *self {
456 Value::Array(ref items) => {
457 if items.len() != 2 {
458 return false;
459 }
460 matches!(items[0], Value::BulkString(_)) && matches!(items[1], Value::Array(_))
461 }
462 _ => false,
463 }
464 }
465
466 pub fn as_sequence(&self) -> Option<&[Value]> {
468 match self {
469 Value::Array(items) => Some(&items[..]),
470 Value::Set(items) => Some(&items[..]),
471 Value::Nil => Some(&[]),
472 _ => None,
473 }
474 }
475
476 pub fn into_sequence(self) -> Result<Vec<Value>, Value> {
479 match self {
480 Value::Array(items) => Ok(items),
481 Value::Set(items) => Ok(items),
482 Value::Nil => Ok(vec![]),
483 _ => Err(self),
484 }
485 }
486
487 pub fn as_map_iter(&self) -> Option<MapIter<'_>> {
489 match self {
490 Value::Array(items) => {
491 if items.len() % 2 == 0 {
492 Some(MapIter::Array(items.iter()))
493 } else {
494 None
495 }
496 }
497 Value::Map(items) => Some(MapIter::Map(items.iter())),
498 _ => None,
499 }
500 }
501
502 pub fn into_map_iter(self) -> Result<OwnedMapIter, Value> {
505 match self {
506 Value::Array(items) => {
507 if items.len() % 2 == 0 {
508 Ok(OwnedMapIter::Array(items.into_iter()))
509 } else {
510 Err(Value::Array(items))
511 }
512 }
513 Value::Map(items) => Ok(OwnedMapIter::Map(items.into_iter())),
514 _ => Err(self),
515 }
516 }
517
518 pub fn extract_error(self) -> RedisResult<Self> {
520 match self {
521 Self::Array(val) => Ok(Self::Array(Self::extract_error_vec(val)?)),
522 Self::Map(map) => Ok(Self::Map(Self::extract_error_map(map)?)),
523 Self::Attribute { data, attributes } => {
524 let data = Box::new((*data).extract_error()?);
525 let attributes = Self::extract_error_map(attributes)?;
526 Ok(Value::Attribute { data, attributes })
527 }
528 Self::Set(set) => Ok(Self::Set(Self::extract_error_vec(set)?)),
529 Self::Push { kind, data } => Ok(Self::Push {
530 kind,
531 data: Self::extract_error_vec(data)?,
532 }),
533 Value::ServerError(err) => Err(err.into()),
534 _ => Ok(self),
535 }
536 }
537
538 pub(crate) fn extract_error_vec(vec: Vec<Self>) -> RedisResult<Vec<Self>> {
539 vec.into_iter()
540 .map(Self::extract_error)
541 .collect::<RedisResult<Vec<_>>>()
542 }
543
544 pub(crate) fn extract_error_map(map: Vec<(Self, Self)>) -> RedisResult<Vec<(Self, Self)>> {
545 let mut vec = Vec::with_capacity(map.len());
546 for (key, value) in map.into_iter() {
547 vec.push((key.extract_error()?, value.extract_error()?));
548 }
549 Ok(vec)
550 }
551
552 fn is_collection_of_len(&self, len: usize) -> bool {
553 match self {
554 Value::Array(values) => values.len() == len,
555 Value::Map(items) => items.len() * 2 == len,
556 Value::Set(values) => values.len() == len,
557 _ => false,
558 }
559 }
560
561 #[cfg(feature = "cluster-async")]
562 pub(crate) fn is_error_that_requires_action(&self) -> bool {
563 matches!(self, Self::ServerError(error) if error.requires_action())
564 }
565}
566
567impl fmt::Debug for Value {
568 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
569 match *self {
570 Value::Nil => write!(fmt, "nil"),
571 Value::Int(val) => write!(fmt, "int({val:?})"),
572 Value::BulkString(ref val) => match from_utf8(val) {
573 Ok(x) => write!(fmt, "bulk-string('{x:?}')"),
574 Err(_) => write!(fmt, "binary-data({val:?})"),
575 },
576 Value::Array(ref values) => write!(fmt, "array({values:?})"),
577 Value::Push { ref kind, ref data } => write!(fmt, "push({kind:?}, {data:?})"),
578 Value::Okay => write!(fmt, "ok"),
579 Value::SimpleString(ref s) => write!(fmt, "simple-string({s:?})"),
580 Value::Map(ref values) => write!(fmt, "map({values:?})"),
581 Value::Attribute {
582 ref data,
583 attributes: _,
584 } => write!(fmt, "attribute({data:?})"),
585 Value::Set(ref values) => write!(fmt, "set({values:?})"),
586 Value::Double(ref d) => write!(fmt, "double({d:?})"),
587 Value::Boolean(ref b) => write!(fmt, "boolean({b:?})"),
588 Value::VerbatimString {
589 ref format,
590 ref text,
591 } => {
592 write!(fmt, "verbatim-string({format:?},{text:?})")
593 }
594 Value::BigNumber(ref m) => write!(fmt, "big-number({m:?})"),
595 Value::ServerError(ref err) => match err.details() {
596 Some(details) => write!(fmt, "Server error: `{}: {details}`", err.code()),
597 None => write!(fmt, "Server error: `{}`", err.code()),
598 },
599 }
600 }
601}
602
603pub type RedisResult<T> = Result<T, RedisError>;
605
606impl<T: FromRedisValue> FromRedisValue for RedisResult<T> {
607 fn from_redis_value_ref(value: &Value) -> Result<Self, ParsingError> {
608 match value {
609 Value::ServerError(err) => Ok(Err(err.clone().into())),
610 _ => from_redis_value_ref(value).map(|result| Ok(result)),
611 }
612 }
613
614 fn from_redis_value(value: Value) -> Result<Self, ParsingError> {
615 match value {
616 Value::ServerError(err) => Ok(Err(err.into())),
617 _ => from_redis_value(value).map(|result| Ok(result)),
618 }
619 }
620}
621
622#[cfg(feature = "aio")]
624pub type RedisFuture<'a, T> = futures_util::future::BoxFuture<'a, RedisResult<T>>;
625
626#[derive(Debug, Clone)]
628pub struct InfoDict {
629 map: HashMap<String, Value>,
630}
631
632impl InfoDict {
649 pub fn new(kvpairs: &str) -> InfoDict {
654 let mut map = HashMap::new();
655 for line in kvpairs.lines() {
656 if line.is_empty() || line.starts_with('#') {
657 continue;
658 }
659 let mut p = line.splitn(2, ':');
660 let (k, v) = match (p.next(), p.next()) {
661 (Some(k), Some(v)) => (k.to_string(), v.to_string()),
662 _ => continue,
663 };
664 map.insert(k, Value::SimpleString(v));
665 }
666 InfoDict { map }
667 }
668
669 pub fn get<T: FromRedisValue>(&self, key: &str) -> Option<T> {
672 match self.find(&key) {
673 Some(x) => from_redis_value_ref(x).ok(),
674 None => None,
675 }
676 }
677
678 pub fn find(&self, key: &&str) -> Option<&Value> {
680 self.map.get(*key)
681 }
682
683 pub fn contains_key(&self, key: &&str) -> bool {
685 self.find(key).is_some()
686 }
687
688 pub fn len(&self) -> usize {
690 self.map.len()
691 }
692
693 pub fn is_empty(&self) -> bool {
695 self.map.is_empty()
696 }
697}
698
699impl Deref for InfoDict {
700 type Target = HashMap<String, Value>;
701
702 fn deref(&self) -> &Self::Target {
703 &self.map
704 }
705}
706
707#[derive(Debug, Clone, Eq, PartialEq)]
711#[non_exhaustive]
712pub enum Role {
713 Primary {
715 replication_offset: u64,
717 replicas: Vec<ReplicaInfo>,
719 },
720 Replica {
722 primary_ip: String,
724 primary_port: u16,
726 replication_state: String,
728 data_received: u64,
730 },
731 Sentinel {
733 primary_names: Vec<String>,
735 },
736}
737
738#[derive(Debug, Clone, Eq, PartialEq)]
742pub struct ReplicaInfo {
743 pub ip: String,
745 pub port: u16,
747 pub replication_offset: i64,
749}
750
751impl FromRedisValue for ReplicaInfo {
752 fn from_redis_value_ref(v: &Value) -> Result<Self, ParsingError> {
753 Self::from_redis_value(v.clone())
754 }
755
756 fn from_redis_value(v: Value) -> Result<Self, ParsingError> {
757 let v = match get_owned_inner_value(v).into_sequence() {
758 Ok(v) => v,
759 Err(v) => crate::errors::invalid_type_error!(v, "Replica response should be an array"),
760 };
761 if v.len() < 3 {
762 crate::errors::invalid_type_error!(v, "Replica array is too short, expected 3 elements")
763 }
764 let mut v = v.into_iter();
765 let ip = from_redis_value(v.next().expect("len was checked"))?;
766 let port = from_redis_value(v.next().expect("len was checked"))?;
767 let offset = from_redis_value(v.next().expect("len was checked"))?;
768 Ok(ReplicaInfo {
769 ip,
770 port,
771 replication_offset: offset,
772 })
773 }
774}
775
776impl FromRedisValue for Role {
777 fn from_redis_value_ref(v: &Value) -> Result<Self, ParsingError> {
778 Self::from_redis_value(v.clone())
779 }
780
781 fn from_redis_value(v: Value) -> Result<Self, ParsingError> {
782 let v = match get_owned_inner_value(v).into_sequence() {
783 Ok(v) => v,
784 Err(v) => crate::errors::invalid_type_error!(v, "Role response should be an array"),
785 };
786 if v.len() < 2 {
787 crate::errors::invalid_type_error!(
788 v,
789 "Role array is too short, expected at least 2 elements"
790 )
791 }
792 match &v[0] {
793 Value::BulkString(role) => match role.as_slice() {
794 b"master" => Role::new_primary(v),
795 b"slave" => Role::new_replica(v),
796 b"sentinel" => Role::new_sentinel(v),
797 _ => crate::errors::invalid_type_error!(
798 v,
799 "Role type is not master, slave or sentinel"
800 ),
801 },
802 _ => crate::errors::invalid_type_error!(v, "Role type is not a bulk string"),
803 }
804 }
805}
806
807impl Role {
808 fn new_primary(values: Vec<Value>) -> Result<Self, ParsingError> {
809 if values.len() < 3 {
810 crate::errors::invalid_type_error!(
811 values,
812 "Role primary response too short, expected 3 elements"
813 )
814 }
815
816 let mut values = values.into_iter();
817 _ = values.next();
818
819 let replication_offset = from_redis_value(values.next().expect("len was checked"))?;
820 let replicas = from_redis_value(values.next().expect("len was checked"))?;
821
822 Ok(Role::Primary {
823 replication_offset,
824 replicas,
825 })
826 }
827
828 fn new_replica(values: Vec<Value>) -> Result<Self, ParsingError> {
829 if values.len() < 5 {
830 crate::errors::invalid_type_error!(
831 values,
832 "Role replica response too short, expected 5 elements"
833 )
834 }
835
836 let mut values = values.into_iter();
837 _ = values.next();
838
839 let primary_ip = from_redis_value(values.next().expect("len was checked"))?;
840 let primary_port = from_redis_value(values.next().expect("len was checked"))?;
841 let replication_state = from_redis_value(values.next().expect("len was checked"))?;
842 let data_received = from_redis_value(values.next().expect("len was checked"))?;
843
844 Ok(Role::Replica {
845 primary_ip,
846 primary_port,
847 replication_state,
848 data_received,
849 })
850 }
851
852 fn new_sentinel(values: Vec<Value>) -> Result<Self, ParsingError> {
853 if values.len() < 2 {
854 crate::errors::invalid_type_error!(
855 values,
856 "Role sentinel response too short, expected at least 2 elements"
857 )
858 }
859 let second_val = values.into_iter().nth(1).expect("len was checked");
860 let primary_names = from_redis_value(second_val)?;
861 Ok(Role::Sentinel { primary_names })
862 }
863}
864
865pub trait RedisWrite {
867 fn write_arg(&mut self, arg: &[u8]);
869
870 fn write_arg_fmt(&mut self, arg: impl fmt::Display) {
872 self.write_arg(arg.to_string().as_bytes())
873 }
874
875 fn writer_for_next_arg(&mut self) -> impl io::Write + '_;
884
885 fn reserve_space_for_args(&mut self, additional: impl IntoIterator<Item = usize>) {
917 let _do_nothing = additional;
920 }
921
922 #[cfg(feature = "bytes")]
923 fn bufmut_for_next_arg(&mut self, capacity: usize) -> impl bytes::BufMut + '_ {
936 struct Wrapper<'a> {
944 buf: Vec<u8>,
946 writer: Box<dyn io::Write + 'a>,
948 }
949 unsafe impl bytes::BufMut for Wrapper<'_> {
950 fn remaining_mut(&self) -> usize {
951 self.buf.remaining_mut()
952 }
953
954 unsafe fn advance_mut(&mut self, cnt: usize) {
955 unsafe {
956 self.buf.advance_mut(cnt);
957 }
958 }
959
960 fn chunk_mut(&mut self) -> &mut bytes::buf::UninitSlice {
961 self.buf.chunk_mut()
962 }
963
964 fn put<T: bytes::buf::Buf>(&mut self, src: T)
966 where
967 Self: Sized,
968 {
969 self.buf.put(src);
970 }
971
972 fn put_slice(&mut self, src: &[u8]) {
973 self.buf.put_slice(src);
974 }
975
976 fn put_bytes(&mut self, val: u8, cnt: usize) {
977 self.buf.put_bytes(val, cnt);
978 }
979 }
980 impl Drop for Wrapper<'_> {
981 fn drop(&mut self) {
982 self.writer.write_all(&self.buf).unwrap()
983 }
984 }
985
986 Wrapper {
987 buf: Vec::with_capacity(capacity),
988 writer: Box::new(self.writer_for_next_arg()),
989 }
990 }
991}
992
993impl RedisWrite for Vec<Vec<u8>> {
994 fn write_arg(&mut self, arg: &[u8]) {
995 self.push(arg.to_owned());
996 }
997
998 fn write_arg_fmt(&mut self, arg: impl fmt::Display) {
999 self.push(arg.to_string().into_bytes())
1000 }
1001
1002 fn writer_for_next_arg(&mut self) -> impl io::Write + '_ {
1003 self.push(Vec::new());
1004 self.last_mut().unwrap()
1005 }
1006
1007 fn reserve_space_for_args(&mut self, additional: impl IntoIterator<Item = usize>) {
1008 self.reserve(additional.into_iter().count());
1013 }
1014
1015 #[cfg(feature = "bytes")]
1016 fn bufmut_for_next_arg(&mut self, capacity: usize) -> impl bytes::BufMut + '_ {
1017 self.push(Vec::with_capacity(capacity));
1018 self.last_mut().unwrap()
1019 }
1020}
1021
1022pub trait ToSingleRedisArg: ToRedisArgs {}
1027
1028pub trait ToRedisArgs: Sized {
1032 fn to_redis_args(&self) -> Vec<Vec<u8>> {
1038 let mut out = Vec::new();
1039 self.write_redis_args(&mut out);
1040 out
1041 }
1042
1043 fn write_redis_args<W>(&self, out: &mut W)
1048 where
1049 W: ?Sized + RedisWrite;
1050
1051 fn describe_numeric_behavior(&self) -> NumericBehavior {
1056 NumericBehavior::NonNumeric
1057 }
1058
1059 fn num_of_args(&self) -> usize {
1066 1
1067 }
1068
1069 #[doc(hidden)]
1072 fn write_args_from_slice<W>(items: &[Self], out: &mut W)
1073 where
1074 W: ?Sized + RedisWrite,
1075 {
1076 Self::make_arg_iter_ref(items.iter(), out)
1077 }
1078
1079 #[doc(hidden)]
1082 fn make_arg_iter_ref<'a, I, W>(items: I, out: &mut W)
1083 where
1084 W: ?Sized + RedisWrite,
1085 I: Iterator<Item = &'a Self>,
1086 Self: 'a,
1087 {
1088 for item in items {
1089 item.write_redis_args(out);
1090 }
1091 }
1092
1093 #[doc(hidden)]
1094 fn is_single_vec_arg(items: &[Self]) -> bool {
1095 items.len() == 1 && items[0].num_of_args() <= 1
1096 }
1097}
1098
1099macro_rules! itoa_based_to_redis_impl {
1100 ($t:ty, $numeric:expr) => {
1101 impl ToRedisArgs for $t {
1102 fn write_redis_args<W>(&self, out: &mut W)
1103 where
1104 W: ?Sized + RedisWrite,
1105 {
1106 let mut buf = ::itoa::Buffer::new();
1107 let s = buf.format(*self);
1108 out.write_arg(s.as_bytes())
1109 }
1110
1111 fn describe_numeric_behavior(&self) -> NumericBehavior {
1112 $numeric
1113 }
1114 }
1115
1116 impl ToSingleRedisArg for $t {}
1117 };
1118}
1119
1120macro_rules! non_zero_itoa_based_to_redis_impl {
1121 ($t:ty, $numeric:expr) => {
1122 impl ToRedisArgs for $t {
1123 fn write_redis_args<W>(&self, out: &mut W)
1124 where
1125 W: ?Sized + RedisWrite,
1126 {
1127 let mut buf = ::itoa::Buffer::new();
1128 let s = buf.format(self.get());
1129 out.write_arg(s.as_bytes())
1130 }
1131
1132 fn describe_numeric_behavior(&self) -> NumericBehavior {
1133 $numeric
1134 }
1135 }
1136
1137 impl ToSingleRedisArg for $t {}
1138 };
1139}
1140
1141macro_rules! ryu_based_to_redis_impl {
1142 ($t:ty, $numeric:expr) => {
1143 impl ToRedisArgs for $t {
1144 fn write_redis_args<W>(&self, out: &mut W)
1145 where
1146 W: ?Sized + RedisWrite,
1147 {
1148 let mut buf = ::ryu::Buffer::new();
1149 let s = buf.format(*self);
1150 out.write_arg(s.as_bytes())
1151 }
1152
1153 fn describe_numeric_behavior(&self) -> NumericBehavior {
1154 $numeric
1155 }
1156 }
1157
1158 impl ToSingleRedisArg for $t {}
1159 };
1160}
1161
1162impl ToRedisArgs for u8 {
1163 fn write_redis_args<W>(&self, out: &mut W)
1164 where
1165 W: ?Sized + RedisWrite,
1166 {
1167 let mut buf = ::itoa::Buffer::new();
1168 let s = buf.format(*self);
1169 out.write_arg(s.as_bytes())
1170 }
1171
1172 fn write_args_from_slice<W>(items: &[u8], out: &mut W)
1173 where
1174 W: ?Sized + RedisWrite,
1175 {
1176 out.write_arg(items);
1177 }
1178
1179 fn is_single_vec_arg(_items: &[u8]) -> bool {
1180 true
1181 }
1182}
1183
1184impl ToSingleRedisArg for u8 {}
1185
1186itoa_based_to_redis_impl!(i8, NumericBehavior::NumberIsInteger);
1187itoa_based_to_redis_impl!(i16, NumericBehavior::NumberIsInteger);
1188itoa_based_to_redis_impl!(u16, NumericBehavior::NumberIsInteger);
1189itoa_based_to_redis_impl!(i32, NumericBehavior::NumberIsInteger);
1190itoa_based_to_redis_impl!(u32, NumericBehavior::NumberIsInteger);
1191itoa_based_to_redis_impl!(i64, NumericBehavior::NumberIsInteger);
1192itoa_based_to_redis_impl!(u64, NumericBehavior::NumberIsInteger);
1193itoa_based_to_redis_impl!(i128, NumericBehavior::NumberIsInteger);
1194itoa_based_to_redis_impl!(u128, NumericBehavior::NumberIsInteger);
1195itoa_based_to_redis_impl!(isize, NumericBehavior::NumberIsInteger);
1196itoa_based_to_redis_impl!(usize, NumericBehavior::NumberIsInteger);
1197
1198non_zero_itoa_based_to_redis_impl!(core::num::NonZeroU8, NumericBehavior::NumberIsInteger);
1199non_zero_itoa_based_to_redis_impl!(core::num::NonZeroI8, NumericBehavior::NumberIsInteger);
1200non_zero_itoa_based_to_redis_impl!(core::num::NonZeroU16, NumericBehavior::NumberIsInteger);
1201non_zero_itoa_based_to_redis_impl!(core::num::NonZeroI16, NumericBehavior::NumberIsInteger);
1202non_zero_itoa_based_to_redis_impl!(core::num::NonZeroU32, NumericBehavior::NumberIsInteger);
1203non_zero_itoa_based_to_redis_impl!(core::num::NonZeroI32, NumericBehavior::NumberIsInteger);
1204non_zero_itoa_based_to_redis_impl!(core::num::NonZeroU64, NumericBehavior::NumberIsInteger);
1205non_zero_itoa_based_to_redis_impl!(core::num::NonZeroI64, NumericBehavior::NumberIsInteger);
1206non_zero_itoa_based_to_redis_impl!(core::num::NonZeroU128, NumericBehavior::NumberIsInteger);
1207non_zero_itoa_based_to_redis_impl!(core::num::NonZeroI128, NumericBehavior::NumberIsInteger);
1208non_zero_itoa_based_to_redis_impl!(core::num::NonZeroUsize, NumericBehavior::NumberIsInteger);
1209non_zero_itoa_based_to_redis_impl!(core::num::NonZeroIsize, NumericBehavior::NumberIsInteger);
1210
1211ryu_based_to_redis_impl!(f32, NumericBehavior::NumberIsFloat);
1212ryu_based_to_redis_impl!(f64, NumericBehavior::NumberIsFloat);
1213
1214#[cfg(any(
1215 feature = "rust_decimal",
1216 feature = "bigdecimal",
1217 feature = "num-bigint"
1218))]
1219macro_rules! bignum_to_redis_impl {
1220 ($t:ty) => {
1221 impl ToRedisArgs for $t {
1222 fn write_redis_args<W>(&self, out: &mut W)
1223 where
1224 W: ?Sized + RedisWrite,
1225 {
1226 out.write_arg(&self.to_string().into_bytes())
1227 }
1228 }
1229
1230 impl ToSingleRedisArg for $t {}
1231 };
1232}
1233
1234#[cfg(feature = "rust_decimal")]
1235bignum_to_redis_impl!(rust_decimal::Decimal);
1236#[cfg(feature = "bigdecimal")]
1237bignum_to_redis_impl!(bigdecimal::BigDecimal);
1238#[cfg(feature = "num-bigint")]
1239bignum_to_redis_impl!(num_bigint::BigInt);
1240#[cfg(feature = "num-bigint")]
1241bignum_to_redis_impl!(num_bigint::BigUint);
1242
1243impl ToRedisArgs for bool {
1244 fn write_redis_args<W>(&self, out: &mut W)
1245 where
1246 W: ?Sized + RedisWrite,
1247 {
1248 out.write_arg(if *self { b"1" } else { b"0" })
1249 }
1250}
1251
1252impl ToSingleRedisArg for bool {}
1253
1254impl ToRedisArgs for String {
1255 fn write_redis_args<W>(&self, out: &mut W)
1256 where
1257 W: ?Sized + RedisWrite,
1258 {
1259 out.write_arg(self.as_bytes())
1260 }
1261}
1262impl ToSingleRedisArg for String {}
1263
1264impl ToRedisArgs for &str {
1265 fn write_redis_args<W>(&self, out: &mut W)
1266 where
1267 W: ?Sized + RedisWrite,
1268 {
1269 out.write_arg(self.as_bytes())
1270 }
1271}
1272
1273impl ToSingleRedisArg for &str {}
1274
1275impl<'a, T> ToRedisArgs for Cow<'a, T>
1276where
1277 T: ToOwned + ?Sized,
1278 &'a T: ToRedisArgs,
1279 T::Owned: ToRedisArgs,
1280{
1281 fn write_redis_args<W>(&self, out: &mut W)
1282 where
1283 W: ?Sized + RedisWrite,
1284 {
1285 match self {
1286 Cow::Borrowed(inner) => inner.write_redis_args(out),
1287 Cow::Owned(inner) => inner.write_redis_args(out),
1288 }
1289 }
1290}
1291
1292impl<'a, T> ToSingleRedisArg for Cow<'a, T>
1293where
1294 T: ToOwned + ?Sized,
1295 &'a T: ToSingleRedisArg,
1296 T::Owned: ToSingleRedisArg,
1297{
1298}
1299
1300impl<T: ToRedisArgs> ToRedisArgs for Option<T> {
1301 fn write_redis_args<W>(&self, out: &mut W)
1302 where
1303 W: ?Sized + RedisWrite,
1304 {
1305 if let Some(ref x) = *self {
1306 x.write_redis_args(out);
1307 }
1308 }
1309
1310 fn describe_numeric_behavior(&self) -> NumericBehavior {
1311 match *self {
1312 Some(ref x) => x.describe_numeric_behavior(),
1313 None => NumericBehavior::NonNumeric,
1314 }
1315 }
1316
1317 fn num_of_args(&self) -> usize {
1318 match *self {
1319 Some(ref x) => x.num_of_args(),
1320 None => 0,
1321 }
1322 }
1323}
1324
1325macro_rules! impl_write_redis_args_for_collection {
1326 ($type:ty) => {
1327 impl<'a, T> ToRedisArgs for $type
1328 where
1329 T: ToRedisArgs,
1330 {
1331 #[inline]
1332 fn write_redis_args<W>(&self, out: &mut W)
1333 where
1334 W: ?Sized + RedisWrite,
1335 {
1336 ToRedisArgs::write_args_from_slice(self, out)
1337 }
1338
1339 fn num_of_args(&self) -> usize {
1340 if ToRedisArgs::is_single_vec_arg(&self[..]) {
1341 return 1;
1342 }
1343 if self.len() == 1 {
1344 self[0].num_of_args()
1345 } else {
1346 self.len()
1347 }
1348 }
1349
1350 fn describe_numeric_behavior(&self) -> NumericBehavior {
1351 NumericBehavior::NonNumeric
1352 }
1353 }
1354 };
1355}
1356
1357macro_rules! deref_to_write_redis_args_impl {
1358 ($type:ty) => {
1359 impl<'a, T> ToRedisArgs for $type
1360 where
1361 T: ToRedisArgs,
1362 {
1363 #[inline]
1364 fn write_redis_args<W>(&self, out: &mut W)
1365 where
1366 W: ?Sized + RedisWrite,
1367 {
1368 (**self).write_redis_args(out)
1369 }
1370
1371 fn num_of_args(&self) -> usize {
1372 (**self).num_of_args()
1373 }
1374
1375 fn describe_numeric_behavior(&self) -> NumericBehavior {
1376 (**self).describe_numeric_behavior()
1377 }
1378 }
1379
1380 impl<'a, T> ToSingleRedisArg for $type where T: ToSingleRedisArg {}
1381 };
1382}
1383
1384deref_to_write_redis_args_impl! {&'a T}
1385deref_to_write_redis_args_impl! {&'a mut T}
1386deref_to_write_redis_args_impl! {Box<T>}
1387deref_to_write_redis_args_impl! {std::sync::Arc<T>}
1388deref_to_write_redis_args_impl! {std::rc::Rc<T>}
1389impl_write_redis_args_for_collection! {&'a [T]}
1390impl_write_redis_args_for_collection! {&'a mut [T]}
1391impl_write_redis_args_for_collection! {Box<[T]>}
1392impl_write_redis_args_for_collection! {std::sync::Arc<[T]>}
1393impl_write_redis_args_for_collection! {std::rc::Rc<[T]>}
1394impl_write_redis_args_for_collection! {Vec<T>}
1395impl ToSingleRedisArg for &[u8] {}
1396impl ToSingleRedisArg for &mut [u8] {}
1397impl ToSingleRedisArg for Vec<u8> {}
1398impl ToSingleRedisArg for Box<[u8]> {}
1399impl ToSingleRedisArg for std::rc::Rc<[u8]> {}
1400impl ToSingleRedisArg for std::sync::Arc<[u8]> {}
1401
1402macro_rules! impl_to_redis_args_for_set {
1406 (for <$($TypeParam:ident),+> $SetType:ty, where ($($WhereClause:tt)+) ) => {
1407 impl< $($TypeParam),+ > ToRedisArgs for $SetType
1408 where
1409 $($WhereClause)+
1410 {
1411 fn write_redis_args<W>(&self, out: &mut W)
1412 where
1413 W: ?Sized + RedisWrite,
1414 {
1415 ToRedisArgs::make_arg_iter_ref(self.iter(), out)
1416 }
1417
1418 fn num_of_args(&self) -> usize {
1419 self.len()
1420 }
1421 }
1422 };
1423}
1424
1425impl_to_redis_args_for_set!(
1426 for <T, S> std::collections::HashSet<T, S>,
1427 where (T: ToRedisArgs)
1428);
1429
1430impl_to_redis_args_for_set!(
1431 for <T> std::collections::BTreeSet<T>,
1432 where (T: ToRedisArgs)
1433);
1434
1435#[cfg(feature = "hashbrown")]
1436impl_to_redis_args_for_set!(
1437 for <T, S> hashbrown::HashSet<T, S>,
1438 where (T: ToRedisArgs)
1439);
1440
1441#[cfg(feature = "ahash")]
1442impl_to_redis_args_for_set!(
1443 for <T, S> ahash::AHashSet<T, S>,
1444 where (T: ToRedisArgs)
1445);
1446
1447macro_rules! impl_to_redis_args_for_map {
1451 (
1452 $(#[$meta:meta])*
1453 for <$($TypeParam:ident),+> $MapType:ty,
1454 where ($($WhereClause:tt)+)
1455 ) => {
1456 $(#[$meta])*
1457 impl< $($TypeParam),+ > ToRedisArgs for $MapType
1458 where
1459 $($WhereClause)+
1460 {
1461 fn write_redis_args<W>(&self, out: &mut W)
1462 where
1463 W: ?Sized + RedisWrite,
1464 {
1465 for (key, value) in self {
1466 assert!(key.num_of_args() <= 1 && value.num_of_args() <= 1);
1468 key.write_redis_args(out);
1469 value.write_redis_args(out);
1470 }
1471 }
1472
1473 fn num_of_args(&self) -> usize {
1474 self.len()
1475 }
1476 }
1477 };
1478}
1479
1480impl_to_redis_args_for_map!(
1481 for <K, V, S> std::collections::HashMap<K, V, S>,
1482 where (K: ToRedisArgs, V: ToRedisArgs)
1483);
1484
1485impl_to_redis_args_for_map!(
1486 for <K, V> std::collections::BTreeMap<K, V>,
1488 where (K: ToRedisArgs, V: ToRedisArgs)
1489);
1490
1491#[cfg(feature = "hashbrown")]
1492impl_to_redis_args_for_map!(
1493 for <K, V, S> hashbrown::HashMap<K, V, S>,
1494 where (K: ToRedisArgs, V: ToRedisArgs)
1495);
1496
1497#[cfg(feature = "ahash")]
1498impl_to_redis_args_for_map!(
1499 for <K, V, S> ahash::AHashMap<K, V, S>,
1500 where (K: ToRedisArgs, V: ToRedisArgs)
1501);
1502
1503macro_rules! to_redis_args_for_tuple {
1504 () => ();
1505 ($(#[$meta:meta],)*$($name:ident,)+) => (
1506 $(#[$meta])*
1507 impl<$($name: ToRedisArgs),*> ToRedisArgs for ($($name,)*) {
1508 #[allow(non_snake_case, unused_variables)]
1511 fn write_redis_args<W>(&self, out: &mut W) where W: ?Sized + RedisWrite {
1512 let ($(ref $name,)*) = *self;
1513 $($name.write_redis_args(out);)*
1514 }
1515
1516 #[allow(non_snake_case, unused_variables)]
1517 fn num_of_args(&self) -> usize {
1518 let mut n: usize = 0;
1519 $(let $name = (); n += 1;)*
1520 n
1521 }
1522 }
1523 )
1524}
1525
1526to_redis_args_for_tuple! { #[cfg_attr(docsrs, doc(fake_variadic))], #[doc = "This trait is implemented for tuples up to 12 items long."], T, }
1527to_redis_args_for_tuple! { #[doc(hidden)], T1, T2, }
1528to_redis_args_for_tuple! { #[doc(hidden)], T1, T2, T3, }
1529to_redis_args_for_tuple! { #[doc(hidden)], T1, T2, T3, T4, }
1530to_redis_args_for_tuple! { #[doc(hidden)], T1, T2, T3, T4, T5, }
1531to_redis_args_for_tuple! { #[doc(hidden)], T1, T2, T3, T4, T5, T6, }
1532to_redis_args_for_tuple! { #[doc(hidden)], T1, T2, T3, T4, T5, T6, T7, }
1533to_redis_args_for_tuple! { #[doc(hidden)], T1, T2, T3, T4, T5, T6, T7, T8, }
1534to_redis_args_for_tuple! { #[doc(hidden)], T1, T2, T3, T4, T5, T6, T7, T8, T9, }
1535to_redis_args_for_tuple! { #[doc(hidden)], T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, }
1536to_redis_args_for_tuple! { #[doc(hidden)], T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, }
1537to_redis_args_for_tuple! { #[doc(hidden)], T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, }
1538
1539impl<T: ToRedisArgs, const N: usize> ToRedisArgs for &[T; N] {
1540 fn write_redis_args<W>(&self, out: &mut W)
1541 where
1542 W: ?Sized + RedisWrite,
1543 {
1544 ToRedisArgs::write_args_from_slice(self.as_slice(), out)
1545 }
1546
1547 fn num_of_args(&self) -> usize {
1548 if ToRedisArgs::is_single_vec_arg(&self[..]) {
1549 return 1;
1550 }
1551 if self.len() == 1 {
1552 self[0].num_of_args()
1553 } else {
1554 self.len()
1555 }
1556 }
1557}
1558impl<const N: usize> ToSingleRedisArg for &[u8; N] {}
1559
1560fn vec_to_array<T, const N: usize>(
1561 items: Vec<T>,
1562 original_value: &Value,
1563) -> Result<[T; N], ParsingError> {
1564 match items.try_into() {
1565 Ok(array) => Ok(array),
1566 Err(items) => {
1567 let msg = format!(
1568 "Response has wrong dimension, expected {N}, got {}",
1569 items.len()
1570 );
1571 crate::errors::invalid_type_error!(original_value, msg)
1572 }
1573 }
1574}
1575
1576impl<T: FromRedisValue, const N: usize> FromRedisValue for [T; N] {
1577 fn from_redis_value_ref(value: &Value) -> Result<[T; N], ParsingError> {
1578 match *value {
1579 Value::BulkString(ref bytes) => match FromRedisValue::from_byte_slice(bytes) {
1580 Some(items) => vec_to_array(items, value),
1581 None => {
1582 let msg = format!(
1583 "Conversion to Array[{}; {N}] failed",
1584 std::any::type_name::<T>()
1585 );
1586 crate::errors::invalid_type_error!(value, msg)
1587 }
1588 },
1589 Value::Array(ref items) => {
1590 let items = FromRedisValue::from_redis_value_refs(items)?;
1591 vec_to_array(items, value)
1592 }
1593 Value::Nil => vec_to_array(vec![], value),
1594 _ => crate::errors::invalid_type_error!(value, "Response type not array compatible"),
1595 }
1596 }
1597
1598 fn from_redis_value(v: Value) -> Result<Self, ParsingError> {
1599 Self::from_redis_value_ref(&v)
1600 }
1601}
1602
1603pub trait FromRedisValue: Sized {
1617 fn from_redis_value_ref(v: &Value) -> Result<Self, ParsingError> {
1621 Self::from_redis_value(v.clone())
1625 }
1626
1627 fn from_redis_value(v: Value) -> Result<Self, ParsingError>;
1631
1632 fn from_redis_value_refs(items: &[Value]) -> Result<Vec<Self>, ParsingError> {
1636 items
1637 .iter()
1638 .map(FromRedisValue::from_redis_value_ref)
1639 .collect()
1640 }
1641
1642 fn from_redis_values(items: Vec<Value>) -> Result<Vec<Self>, ParsingError> {
1645 items
1646 .into_iter()
1647 .map(FromRedisValue::from_redis_value)
1648 .collect()
1649 }
1650
1651 fn from_each_redis_values(items: Vec<Value>) -> Vec<Result<Self, ParsingError>> {
1654 items
1655 .into_iter()
1656 .map(FromRedisValue::from_redis_value)
1657 .collect()
1658 }
1659
1660 fn from_byte_slice(_vec: &[u8]) -> Option<Vec<Self>> {
1662 Self::from_redis_value(Value::BulkString(_vec.into()))
1663 .map(|rv| vec![rv])
1664 .ok()
1665 }
1666
1667 fn from_byte_vec(_vec: Vec<u8>) -> Result<Vec<Self>, ParsingError> {
1669 Self::from_redis_value(Value::BulkString(_vec)).map(|rv| vec![rv])
1670 }
1671}
1672
1673fn get_inner_value(v: &Value) -> &Value {
1674 if let Value::Attribute {
1675 data,
1676 attributes: _,
1677 } = v
1678 {
1679 data.as_ref()
1680 } else {
1681 v
1682 }
1683}
1684
1685fn get_owned_inner_value(v: Value) -> Value {
1686 if let Value::Attribute {
1687 data,
1688 attributes: _,
1689 } = v
1690 {
1691 *data
1692 } else {
1693 v
1694 }
1695}
1696
1697macro_rules! from_redis_value_for_num_internal {
1698 ($t:ty, $v:expr) => {{
1699 let v = if let Value::Attribute {
1700 data,
1701 attributes: _,
1702 } = $v
1703 {
1704 data
1705 } else {
1706 $v
1707 };
1708 match *v {
1709 Value::Int(val) => Ok(val as $t),
1710 Value::SimpleString(ref s) => match s.parse::<$t>() {
1711 Ok(rv) => Ok(rv),
1712 Err(_) => crate::errors::invalid_type_error!(v, "Could not convert from string."),
1713 },
1714 Value::BulkString(ref bytes) => match from_utf8(bytes)?.parse::<$t>() {
1715 Ok(rv) => Ok(rv),
1716 Err(_) => crate::errors::invalid_type_error!(v, "Could not convert from string."),
1717 },
1718 Value::Double(val) => Ok(val as $t),
1719 _ => crate::errors::invalid_type_error!(v, "Response type not convertible to numeric."),
1720 }
1721 }};
1722}
1723
1724macro_rules! from_redis_value_for_num {
1725 ($t:ty) => {
1726 impl FromRedisValue for $t {
1727 fn from_redis_value_ref(v: &Value) -> Result<$t, ParsingError> {
1728 from_redis_value_for_num_internal!($t, v)
1729 }
1730
1731 fn from_redis_value(v: Value) -> Result<Self, ParsingError> {
1732 Self::from_redis_value_ref(&v)
1733 }
1734 }
1735 };
1736}
1737
1738impl FromRedisValue for u8 {
1739 fn from_redis_value_ref(v: &Value) -> Result<u8, ParsingError> {
1740 from_redis_value_for_num_internal!(u8, v)
1741 }
1742
1743 fn from_redis_value(v: Value) -> Result<Self, ParsingError> {
1744 Self::from_redis_value_ref(&v)
1745 }
1746
1747 fn from_byte_slice(vec: &[u8]) -> Option<Vec<u8>> {
1749 Some(vec.to_vec())
1750 }
1751 fn from_byte_vec(vec: Vec<u8>) -> Result<Vec<u8>, ParsingError> {
1752 Ok(vec)
1753 }
1754}
1755
1756from_redis_value_for_num!(i8);
1757from_redis_value_for_num!(i16);
1758from_redis_value_for_num!(u16);
1759from_redis_value_for_num!(i32);
1760from_redis_value_for_num!(u32);
1761from_redis_value_for_num!(i64);
1762from_redis_value_for_num!(u64);
1763from_redis_value_for_num!(i128);
1764from_redis_value_for_num!(u128);
1765from_redis_value_for_num!(f32);
1766from_redis_value_for_num!(f64);
1767from_redis_value_for_num!(isize);
1768from_redis_value_for_num!(usize);
1769
1770#[cfg(any(
1771 feature = "rust_decimal",
1772 feature = "bigdecimal",
1773 feature = "num-bigint"
1774))]
1775macro_rules! from_redis_value_for_bignum_internal {
1776 ($t:ty, $v:expr) => {{
1777 let v = $v;
1778 match *v {
1779 Value::Int(val) => <$t>::try_from(val).map_err(|_| {
1780 crate::errors::invalid_type_error_inner!(v, "Could not convert from integer.")
1781 }),
1782 Value::SimpleString(ref s) => match s.parse::<$t>() {
1783 Ok(rv) => Ok(rv),
1784 Err(_) => crate::errors::invalid_type_error!(v, "Could not convert from string."),
1785 },
1786 Value::BulkString(ref bytes) => match from_utf8(bytes)?.parse::<$t>() {
1787 Ok(rv) => Ok(rv),
1788 Err(_) => crate::errors::invalid_type_error!(v, "Could not convert from string."),
1789 },
1790 _ => crate::errors::invalid_type_error!(v, "Response type not convertible to numeric."),
1791 }
1792 }};
1793}
1794
1795#[cfg(any(
1796 feature = "rust_decimal",
1797 feature = "bigdecimal",
1798 feature = "num-bigint"
1799))]
1800macro_rules! from_redis_value_for_bignum {
1801 ($t:ty) => {
1802 impl FromRedisValue for $t {
1803 fn from_redis_value_ref(v: &Value) -> Result<$t, ParsingError> {
1804 from_redis_value_for_bignum_internal!($t, v)
1805 }
1806
1807 fn from_redis_value(v: Value) -> Result<Self, ParsingError> {
1808 Self::from_redis_value_ref(&v)
1809 }
1810 }
1811 };
1812}
1813
1814#[cfg(feature = "rust_decimal")]
1815from_redis_value_for_bignum!(rust_decimal::Decimal);
1816#[cfg(feature = "bigdecimal")]
1817from_redis_value_for_bignum!(bigdecimal::BigDecimal);
1818#[cfg(feature = "num-bigint")]
1819from_redis_value_for_bignum!(num_bigint::BigInt);
1820#[cfg(feature = "num-bigint")]
1821from_redis_value_for_bignum!(num_bigint::BigUint);
1822
1823impl FromRedisValue for bool {
1824 fn from_redis_value_ref(v: &Value) -> Result<bool, ParsingError> {
1825 let v = get_inner_value(v);
1826 match *v {
1827 Value::Nil => Ok(false),
1828 Value::Int(val) => Ok(val != 0),
1829 Value::SimpleString(ref s) => {
1830 if &s[..] == "1" {
1831 Ok(true)
1832 } else if &s[..] == "0" {
1833 Ok(false)
1834 } else {
1835 crate::errors::invalid_type_error!(v, "Response status not valid boolean");
1836 }
1837 }
1838 Value::BulkString(ref bytes) => {
1839 if bytes == b"1" {
1840 Ok(true)
1841 } else if bytes == b"0" {
1842 Ok(false)
1843 } else {
1844 crate::errors::invalid_type_error!(v, "Response type not bool compatible.");
1845 }
1846 }
1847 Value::Boolean(b) => Ok(b),
1848 Value::Okay => Ok(true),
1849 _ => crate::errors::invalid_type_error!(v, "Response type not bool compatible."),
1850 }
1851 }
1852
1853 fn from_redis_value(v: Value) -> Result<Self, ParsingError> {
1854 Self::from_redis_value_ref(&v)
1855 }
1856}
1857
1858impl FromRedisValue for CString {
1859 fn from_redis_value_ref(v: &Value) -> Result<CString, ParsingError> {
1860 let v = get_inner_value(v);
1861 match *v {
1862 Value::BulkString(ref bytes) => Ok(CString::new(bytes.as_slice())?),
1863 Value::Okay => Ok(CString::new("OK")?),
1864 Value::SimpleString(ref val) => Ok(CString::new(val.as_bytes())?),
1865 _ => crate::errors::invalid_type_error!(v, "Response type not CString compatible."),
1866 }
1867 }
1868 fn from_redis_value(v: Value) -> Result<CString, ParsingError> {
1869 let v = get_owned_inner_value(v);
1870 match v {
1871 Value::BulkString(bytes) => Ok(CString::new(bytes)?),
1872 Value::Okay => Ok(CString::new("OK")?),
1873 Value::SimpleString(val) => Ok(CString::new(val)?),
1874 _ => crate::errors::invalid_type_error!(v, "Response type not CString compatible."),
1875 }
1876 }
1877}
1878
1879impl FromRedisValue for String {
1880 fn from_redis_value_ref(v: &Value) -> Result<Self, ParsingError> {
1881 let v = get_inner_value(v);
1882 match *v {
1883 Value::BulkString(ref bytes) => Ok(from_utf8(bytes)?.to_string()),
1884 Value::Okay => Ok("OK".to_string()),
1885 Value::SimpleString(ref val) => Ok(val.to_string()),
1886 Value::VerbatimString {
1887 format: _,
1888 ref text,
1889 } => Ok(text.to_string()),
1890 Value::Double(ref val) => Ok(val.to_string()),
1891 Value::Int(val) => Ok(val.to_string()),
1892 _ => crate::errors::invalid_type_error!(v, "Response type not string compatible."),
1893 }
1894 }
1895
1896 fn from_redis_value(v: Value) -> Result<Self, ParsingError> {
1897 let v = get_owned_inner_value(v);
1898 match v {
1899 Value::BulkString(bytes) => Ok(Self::from_utf8(bytes)?),
1900 Value::Okay => Ok("OK".to_string()),
1901 Value::SimpleString(val) => Ok(val),
1902 Value::VerbatimString { format: _, text } => Ok(text),
1903 Value::Double(val) => Ok(val.to_string()),
1904 Value::Int(val) => Ok(val.to_string()),
1905 _ => crate::errors::invalid_type_error!(v, "Response type not string compatible."),
1906 }
1907 }
1908}
1909
1910macro_rules! pointer_from_redis_value_impl {
1911 (
1912 $(#[$attr:meta])*
1913 $id:ident, $ty:ty, $func:expr
1914 ) => {
1915 $(#[$attr])*
1916 impl<$id: FromRedisValue> FromRedisValue for $ty {
1917 fn from_redis_value_ref(v: &Value) -> Result<Self, ParsingError>
1918 {
1919 FromRedisValue::from_redis_value_ref(v).map($func)
1920 }
1921
1922 fn from_redis_value(v: Value) -> Result<Self, ParsingError>{
1923 FromRedisValue::from_redis_value(v).map($func)
1924 }
1925 }
1926 }
1927}
1928
1929pointer_from_redis_value_impl!(T, Box<T>, Box::new);
1930pointer_from_redis_value_impl!(T, std::sync::Arc<T>, std::sync::Arc::new);
1931pointer_from_redis_value_impl!(T, std::rc::Rc<T>, std::rc::Rc::new);
1932
1933macro_rules! from_vec_from_redis_value {
1938 (<$T:ident> $Type:ty) => {
1939 from_vec_from_redis_value!(<$T> $Type; Into::into);
1940 };
1941
1942 (<$T:ident> $Type:ty; $convert:expr) => {
1943 impl<$T: FromRedisValue> FromRedisValue for $Type {
1944 fn from_redis_value_ref(v: &Value) -> Result<$Type, ParsingError> {
1945 match v {
1946 Value::BulkString(bytes) => match FromRedisValue::from_byte_slice(bytes) {
1949 Some(x) => Ok($convert(x)),
1950 None => crate::errors::invalid_type_error!(
1951 v,
1952 format!("Conversion to {} failed.", std::any::type_name::<$Type>())
1953 ),
1954 },
1955 Value::Array(items) => FromRedisValue::from_redis_value_refs(items).map($convert),
1956 Value::Set(items) => FromRedisValue::from_redis_value_refs(items).map($convert),
1957 Value::Map(items) => {
1958 let mut n: Vec<T> = vec![];
1959 for item in items {
1960 match FromRedisValue::from_redis_value_ref(&Value::Map(vec![item.clone()])) {
1961 Ok(v) => {
1962 n.push(v);
1963 }
1964 Err(e) => {
1965 return Err(e);
1966 }
1967 }
1968 }
1969 Ok($convert(n))
1970 }
1971 Value::Nil => Ok($convert(Vec::new())),
1972 _ => crate::errors::invalid_type_error!(v, "Response type not vector compatible."),
1973 }
1974 }
1975 fn from_redis_value(v: Value) -> Result<$Type, ParsingError> {
1976 match v {
1977 Value::BulkString(bytes) => FromRedisValue::from_byte_vec(bytes).map($convert),
1981 Value::Array(items) => FromRedisValue::from_redis_values(items).map($convert),
1982 Value::Set(items) => FromRedisValue::from_redis_values(items).map($convert),
1983 Value::Map(items) => {
1984 let mut n: Vec<T> = vec![];
1985 for item in items {
1986 match FromRedisValue::from_redis_value(Value::Map(vec![item])) {
1987 Ok(v) => {
1988 n.push(v);
1989 }
1990 Err(e) => {
1991 return Err(e);
1992 }
1993 }
1994 }
1995 Ok($convert(n))
1996 }
1997 Value::Nil => Ok($convert(Vec::new())),
1998 _ => crate::errors::invalid_type_error!(v, "Response type not vector compatible."),
1999 }
2000 }
2001 }
2002 };
2003}
2004
2005from_vec_from_redis_value!(<T> Vec<T>);
2006from_vec_from_redis_value!(<T> std::sync::Arc<[T]>);
2007from_vec_from_redis_value!(<T> Box<[T]>; Vec::into_boxed_slice);
2008
2009macro_rules! impl_from_redis_value_for_map {
2010 (for <$($TypeParam:ident),+> $MapType:ty, where ($($WhereClause:tt)+)) => {
2011 impl< $($TypeParam),+ > FromRedisValue for $MapType
2012 where
2013 $($WhereClause)+
2014 {
2015 fn from_redis_value_ref(v: &Value) -> Result<$MapType, ParsingError> {
2016 let v = get_inner_value(v);
2017 match *v {
2018 Value::Nil => Ok(Default::default()),
2019 _ => v
2020 .as_map_iter()
2021 .ok_or_else(|| crate::errors::invalid_type_error_inner!(v, "Response type not map compatible"))?
2022 .map(|(k, v)| {
2023 Ok((from_redis_value_ref(k)?, from_redis_value_ref(v)?))
2024 })
2025 .collect(),
2026 }
2027 }
2028
2029 fn from_redis_value(v: Value) -> Result<$MapType, ParsingError> {
2030 let v = get_owned_inner_value(v);
2031 match v {
2032 Value::Nil => Ok(Default::default()),
2033 _ => v
2034 .into_map_iter()
2035 .map_err(|v| crate::errors::invalid_type_error_inner!(v, "Response type not map compatible"))?
2036 .map(|(k, v)| {
2037 Ok((from_redis_value(k)?, from_redis_value(v)?))
2038 })
2039 .collect(),
2040 }
2041 }
2042 }
2043 };
2044}
2045
2046impl_from_redis_value_for_map!(
2047 for <K, V, S> std::collections::HashMap<K, V, S>,
2048 where (K: FromRedisValue + Eq + Hash, V: FromRedisValue, S: BuildHasher + Default)
2049);
2050
2051impl_from_redis_value_for_map!(
2052 for <K, V> std::collections::BTreeMap<K, V>,
2053 where (K: FromRedisValue + Eq + Ord, V: FromRedisValue)
2054);
2055
2056#[cfg(feature = "hashbrown")]
2057impl_from_redis_value_for_map!(
2058 for <K, V, S> hashbrown::HashMap<K, V, S>,
2059 where (K: FromRedisValue + Eq + Hash, V: FromRedisValue, S: BuildHasher + Default)
2060);
2061
2062#[cfg(feature = "ahash")]
2064impl_from_redis_value_for_map!(
2065 for <K, V> ahash::AHashMap<K, V>,
2066 where (K: FromRedisValue + Eq + Hash, V: FromRedisValue)
2067);
2068
2069macro_rules! impl_from_redis_value_for_set {
2070 (for <$($TypeParam:ident),+> $SetType:ty, where ($($WhereClause:tt)+)) => {
2071 impl< $($TypeParam),+ > FromRedisValue for $SetType
2072 where
2073 $($WhereClause)+
2074 {
2075 fn from_redis_value_ref(v: &Value) -> Result<$SetType, ParsingError> {
2076 let v = get_inner_value(v);
2077 let items = v
2078 .as_sequence()
2079 .ok_or_else(|| crate::errors::invalid_type_error_inner!(v, "Response type not map compatible"))?;
2080 items.iter().map(|item| from_redis_value_ref(item)).collect()
2081 }
2082
2083 fn from_redis_value(v: Value) -> Result<$SetType, ParsingError> {
2084 let v = get_owned_inner_value(v);
2085 let items = v
2086 .into_sequence()
2087 .map_err(|v| crate::errors::invalid_type_error_inner!(v, "Response type not map compatible"))?;
2088 items
2089 .into_iter()
2090 .map(|item| from_redis_value(item))
2091 .collect()
2092 }
2093 }
2094 };
2095}
2096
2097impl_from_redis_value_for_set!(
2098 for <T, S> std::collections::HashSet<T, S>,
2099 where (T: FromRedisValue + Eq + Hash, S: BuildHasher + Default)
2100);
2101
2102impl_from_redis_value_for_set!(
2103 for <T> std::collections::BTreeSet<T>,
2104 where (T: FromRedisValue + Ord)
2105);
2106
2107#[cfg(feature = "hashbrown")]
2108impl_from_redis_value_for_set!(
2109 for <T, S> hashbrown::HashSet<T, S>,
2110 where (T: FromRedisValue + Eq + Hash, S: BuildHasher + Default)
2111);
2112
2113#[cfg(feature = "ahash")]
2115impl_from_redis_value_for_set!(
2116 for <T> ahash::AHashSet<T>,
2117 where (T: FromRedisValue + Eq + Hash)
2118);
2119
2120impl FromRedisValue for Value {
2121 fn from_redis_value_ref(v: &Value) -> Result<Value, ParsingError> {
2122 Ok(v.clone())
2123 }
2124
2125 fn from_redis_value(v: Value) -> Result<Self, ParsingError> {
2126 Ok(v)
2127 }
2128}
2129
2130impl FromRedisValue for () {
2131 fn from_redis_value_ref(v: &Value) -> Result<(), ParsingError> {
2132 match v {
2133 Value::ServerError(err) => Err(ParsingError::from(err.to_string())),
2134 _ => Ok(()),
2135 }
2136 }
2137
2138 fn from_redis_value(v: Value) -> Result<(), ParsingError> {
2139 Self::from_redis_value_ref(&v)
2140 }
2141}
2142
2143macro_rules! from_redis_value_for_tuple {
2144 () => ();
2145 ($(#[$meta:meta],)*$($name:ident,)+) => (
2146 $(#[$meta])*
2147 impl<$($name: FromRedisValue),*> FromRedisValue for ($($name,)*) {
2148 #[allow(non_snake_case, unused_variables)]
2151 fn from_redis_value_ref(v: &Value) -> Result<($($name,)*), ParsingError> {
2152 let v = get_inner_value(v);
2153 let mut n = 0;
2155 $(let $name = (); n += 1;)*
2156
2157 match *v {
2158 Value::Array(ref items) => {
2159 if items.len() != n {
2160 crate::errors::invalid_type_error!(v, "Array response of wrong dimension")
2161 }
2162
2163 let mut i = 0;
2165 Ok(($({let $name = (); from_redis_value_ref(
2166 &items[{ i += 1; i - 1 }])?},)*))
2167 }
2168
2169 Value::Set(ref items) => {
2170 if items.len() != n {
2171 crate::errors::invalid_type_error!(v, "Set response of wrong dimension")
2172 }
2173
2174 let mut i = 0;
2176 Ok(($({let $name = (); from_redis_value_ref(
2177 &items[{ i += 1; i - 1 }])?},)*))
2178 }
2179
2180 Value::Map(ref items) => {
2181 if n != items.len() * 2 {
2182 crate::errors::invalid_type_error!(v, "Map response of wrong dimension")
2183 }
2184
2185 let mut flatten_items = items.iter().map(|(a,b)|[a,b]).flatten();
2186
2187 Ok(($({let $name = (); from_redis_value_ref(
2188 &flatten_items.next().unwrap())?},)*))
2189 }
2190
2191 _ => crate::errors::invalid_type_error!(v, "Not a Array response")
2192 }
2193 }
2194
2195 #[allow(non_snake_case, unused_variables)]
2198 fn from_redis_value(v: Value) -> Result<($($name,)*), ParsingError> {
2199 let v = get_owned_inner_value(v);
2200 let mut n = 0;
2202 $(let $name = (); n += 1;)*
2203 match v {
2204 Value::Array(mut items) => {
2205 if items.len() != n {
2206 crate::errors::invalid_type_error!(Value::Array(items), "Array response of wrong dimension")
2207 }
2208
2209 let mut i = 0;
2211 Ok(($({let $name = (); from_redis_value(
2212 ::std::mem::replace(&mut items[{ i += 1; i - 1 }], Value::Nil)
2213 )?},)*))
2214 }
2215
2216 Value::Set(mut items) => {
2217 if items.len() != n {
2218 crate::errors::invalid_type_error!(Value::Array(items), "Set response of wrong dimension")
2219 }
2220
2221 let mut i = 0;
2223 Ok(($({let $name = (); from_redis_value(
2224 ::std::mem::replace(&mut items[{ i += 1; i - 1 }], Value::Nil)
2225 )?},)*))
2226 }
2227
2228 Value::Map(items) => {
2229 if n != items.len() * 2 {
2230 crate::errors::invalid_type_error!(Value::Map(items), "Map response of wrong dimension")
2231 }
2232
2233 let mut flatten_items = items.into_iter().map(|(a,b)|[a,b]).flatten();
2234
2235 Ok(($({let $name = (); from_redis_value(
2236 ::std::mem::replace(&mut flatten_items.next().unwrap(), Value::Nil)
2237 )?},)*))
2238 }
2239
2240 _ => crate::errors::invalid_type_error!(v, "Not a Array response")
2241 }
2242 }
2243
2244 #[allow(non_snake_case, unused_variables)]
2245 fn from_redis_value_refs(items: &[Value]) -> Result<Vec<($($name,)*)>, ParsingError> {
2246 let mut n = 0;
2248 $(let $name = (); n += 1;)*
2249 if items.len() == 0 {
2250 return Ok(vec![]);
2251 }
2252
2253 if items.iter().all(|item| item.is_collection_of_len(n)) {
2254 return items.iter().map(|item| from_redis_value_ref(item)).collect();
2255 }
2256
2257 let mut rv = Vec::with_capacity(items.len() / n);
2258 if let [$($name),*] = items {
2259 rv.push(($(from_redis_value_ref($name)?,)*));
2260 return Ok(rv);
2261 }
2262 for chunk in items.chunks(n) {
2263 match chunk {
2264 [$($name),*] => rv.push(($(from_redis_value_ref($name)?,)*)),
2265 _ => return Err(format!("Vector of length {} doesn't have arity of {n}", items.len()).into()),
2266 }
2267 }
2268 Ok(rv)
2269 }
2270
2271 #[allow(non_snake_case, unused_variables)]
2272 fn from_each_redis_values(mut items: Vec<Value>) -> Vec<Result<($($name,)*), ParsingError>> {
2273 #[allow(unused_parens)]
2274 let extract = |val: ($(Result<$name, ParsingError>,)*)| -> Result<($($name,)*), ParsingError> {
2275 let ($($name,)*) = val;
2276 Ok(($($name?,)*))
2277 };
2278
2279 let mut n = 0;
2281 $(let $name = (); n += 1;)*
2282
2283 if items.len() == 0 {
2285 return vec![];
2286 }
2287 if items.iter().all(|item| item.is_collection_of_len(n)) {
2288 return items.into_iter().map(|item| from_redis_value(item).map_err(|err|err.into())).collect();
2289 }
2290
2291 let mut rv = Vec::with_capacity(items.len() / n);
2292
2293 for chunk in items.chunks_mut(n) {
2294 match chunk {
2295 [$($name),*] => rv.push(extract(($(from_redis_value(std::mem::replace($name, Value::Nil)).into(),)*))),
2300 _ => return vec![Err(format!("Vector of length {} doesn't have arity of {n}", items.len()).into())],
2301 }
2302 }
2303 rv
2304 }
2305
2306 #[allow(non_snake_case, unused_variables)]
2307 fn from_redis_values(mut items: Vec<Value>) -> Result<Vec<($($name,)*)>, ParsingError> {
2308 let mut n = 0;
2310 $(let $name = (); n += 1;)*
2311
2312 if items.len() == 0 {
2314 return Ok(vec![])
2315 }
2316 if items.iter().all(|item| item.is_collection_of_len(n)) {
2317 return items.into_iter().map(|item| from_redis_value(item)).collect();
2318 }
2319
2320 let mut rv = Vec::with_capacity(items.len() / n);
2321 for chunk in items.chunks_mut(n) {
2322 match chunk {
2323 [$($name),*] => rv.push(($(from_redis_value(std::mem::replace($name, Value::Nil))?,)*)),
2328 _ => return Err(format!("Vector of length {} doesn't have arity of {n}", items.len()).into()),
2329 }
2330 }
2331 Ok(rv)
2332 }
2333 }
2334 )
2335}
2336
2337from_redis_value_for_tuple! { #[cfg_attr(docsrs, doc(fake_variadic))], #[doc = "This trait is implemented for tuples up to 12 items long."], T, }
2338from_redis_value_for_tuple! { #[doc(hidden)], T1, T2, }
2339from_redis_value_for_tuple! { #[doc(hidden)], T1, T2, T3, }
2340from_redis_value_for_tuple! { #[doc(hidden)], T1, T2, T3, T4, }
2341from_redis_value_for_tuple! { #[doc(hidden)], T1, T2, T3, T4, T5, }
2342from_redis_value_for_tuple! { #[doc(hidden)], T1, T2, T3, T4, T5, T6, }
2343from_redis_value_for_tuple! { #[doc(hidden)], T1, T2, T3, T4, T5, T6, T7, }
2344from_redis_value_for_tuple! { #[doc(hidden)], T1, T2, T3, T4, T5, T6, T7, T8, }
2345from_redis_value_for_tuple! { #[doc(hidden)], T1, T2, T3, T4, T5, T6, T7, T8, T9, }
2346from_redis_value_for_tuple! { #[doc(hidden)], T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, }
2347from_redis_value_for_tuple! { #[doc(hidden)], T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, }
2348from_redis_value_for_tuple! { #[doc(hidden)], T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, }
2349
2350impl FromRedisValue for InfoDict {
2351 fn from_redis_value_ref(v: &Value) -> Result<InfoDict, ParsingError> {
2352 let v = get_inner_value(v);
2353 let s: String = from_redis_value_ref(v)?;
2354 Ok(InfoDict::new(&s))
2355 }
2356 fn from_redis_value(v: Value) -> Result<InfoDict, ParsingError> {
2357 let v = get_owned_inner_value(v);
2358 let s: String = from_redis_value(v)?;
2359 Ok(InfoDict::new(&s))
2360 }
2361}
2362
2363impl<T: FromRedisValue> FromRedisValue for Option<T> {
2364 fn from_redis_value_ref(v: &Value) -> Result<Option<T>, ParsingError> {
2365 let v = get_inner_value(v);
2366 if *v == Value::Nil {
2367 return Ok(None);
2368 }
2369 Ok(Some(from_redis_value_ref(v)?))
2370 }
2371 fn from_redis_value(v: Value) -> Result<Option<T>, ParsingError> {
2372 let v = get_owned_inner_value(v);
2373 if v == Value::Nil {
2374 return Ok(None);
2375 }
2376 Ok(Some(from_redis_value(v)?))
2377 }
2378}
2379
2380#[cfg(feature = "bytes")]
2381impl FromRedisValue for bytes::Bytes {
2382 fn from_redis_value_ref(v: &Value) -> Result<Self, ParsingError> {
2383 let v = get_inner_value(v);
2384 match v {
2385 Value::BulkString(bytes_vec) => Ok(bytes::Bytes::copy_from_slice(bytes_vec.as_ref())),
2386 _ => crate::errors::invalid_type_error!(v, "Not a bulk string"),
2387 }
2388 }
2389 fn from_redis_value(v: Value) -> Result<Self, ParsingError> {
2390 let v = get_owned_inner_value(v);
2391 match v {
2392 Value::BulkString(bytes_vec) => Ok(bytes_vec.into()),
2393 _ => crate::errors::invalid_type_error!(v, "Not a bulk string"),
2394 }
2395 }
2396}
2397
2398#[cfg(feature = "uuid")]
2399impl FromRedisValue for uuid::Uuid {
2400 fn from_redis_value_ref(v: &Value) -> Result<Self, ParsingError> {
2401 match *v {
2402 Value::BulkString(ref bytes) => Ok(uuid::Uuid::from_slice(bytes)?),
2403 _ => crate::errors::invalid_type_error!(v, "Response type not uuid compatible."),
2404 }
2405 }
2406
2407 fn from_redis_value(v: Value) -> Result<Self, ParsingError> {
2408 Self::from_redis_value_ref(&v)
2409 }
2410}
2411
2412#[cfg(feature = "uuid")]
2413impl ToRedisArgs for uuid::Uuid {
2414 fn write_redis_args<W>(&self, out: &mut W)
2415 where
2416 W: ?Sized + RedisWrite,
2417 {
2418 out.write_arg(self.as_bytes());
2419 }
2420}
2421
2422#[cfg(feature = "uuid")]
2423impl ToSingleRedisArg for uuid::Uuid {}
2424
2425pub fn from_redis_value_ref<T: FromRedisValue>(v: &Value) -> Result<T, ParsingError> {
2428 FromRedisValue::from_redis_value_ref(v)
2429}
2430
2431pub fn from_redis_value<T: FromRedisValue>(v: Value) -> Result<T, ParsingError> {
2434 FromRedisValue::from_redis_value(v)
2435}
2436
2437pub fn calculate_value_digest<T: ToRedisArgs>(value: T) -> String {
2453 use xxhash_rust::xxh3::xxh3_64;
2454
2455 let args = value.to_redis_args();
2457
2458 let mut combined_bytes = Vec::new();
2461 for arg in args {
2462 combined_bytes.extend_from_slice(&arg);
2463 }
2464
2465 let hash = xxh3_64(&combined_bytes);
2467 format!("{:016x}", hash)
2468}
2469
2470pub fn is_valid_16_bytes_hex_digest(s: &str) -> bool {
2472 s.len() == 16 && s.chars().all(|c| c.is_ascii_hexdigit())
2473}
2474
2475#[derive(Clone, Eq, PartialEq, Default, Debug, Copy)]
2480#[non_exhaustive]
2481pub enum ProtocolVersion {
2482 #[default]
2484 RESP2,
2485 RESP3,
2487}
2488
2489impl ProtocolVersion {
2490 pub fn supports_resp3(&self) -> bool {
2492 !matches!(self, ProtocolVersion::RESP2)
2493 }
2494}
2495
2496#[derive(Clone, Copy)]
2498#[non_exhaustive]
2499pub enum ExpireOption {
2500 NONE,
2502 NX,
2504 XX,
2506 GT,
2508 LT,
2510}
2511
2512impl ToRedisArgs for ExpireOption {
2513 fn write_redis_args<W>(&self, out: &mut W)
2514 where
2515 W: ?Sized + RedisWrite,
2516 {
2517 match self {
2518 ExpireOption::NX => out.write_arg(b"NX"),
2519 ExpireOption::XX => out.write_arg(b"XX"),
2520 ExpireOption::GT => out.write_arg(b"GT"),
2521 ExpireOption::LT => out.write_arg(b"LT"),
2522 _ => {}
2523 }
2524 }
2525}
2526
2527#[derive(Debug, Clone, PartialEq)]
2528pub struct PushInfo {
2530 pub kind: PushKind,
2532 pub data: Vec<Value>,
2534}
2535
2536impl PushInfo {
2537 pub(crate) fn disconnect() -> Self {
2538 PushInfo {
2539 kind: crate::PushKind::Disconnection,
2540 data: vec![],
2541 }
2542 }
2543}
2544
2545pub(crate) type SyncPushSender = std::sync::mpsc::Sender<PushInfo>;
2546
2547#[derive(Debug, Clone, PartialEq)]
2549#[non_exhaustive]
2550pub enum ValueType {
2551 None,
2553 String,
2555 List,
2557 Set,
2559 ZSet,
2561 Hash,
2563 Stream,
2565 VectorSet,
2567 JSON,
2569 BloomFilterRedis,
2571 CuckooFilter,
2573 CountMin,
2575 TDigest,
2577 TopK,
2579 TimeSeries,
2581 Trie,
2583 BloomFilterValKey,
2585 Unknown(String),
2587}
2588
2589impl<T: AsRef<str>> From<T> for ValueType {
2590 fn from(s: T) -> Self {
2591 match s.as_ref() {
2592 "none" => ValueType::None,
2593 "string" => ValueType::String,
2594 "list" => ValueType::List,
2595 "set" => ValueType::Set,
2596 "zset" => ValueType::ZSet,
2597 "hash" => ValueType::Hash,
2598 "stream" => ValueType::Stream,
2599 "vectorset" => ValueType::VectorSet,
2600 "ReJSON-RL" => ValueType::JSON,
2602 "CMSk-TYPE" => ValueType::CountMin,
2604 "MBbloom--" => ValueType::BloomFilterRedis,
2605 "MBbloomCF" => ValueType::CuckooFilter,
2606 "TDIS-TYPE" => ValueType::TDigest,
2607 "TopK-TYPE" => ValueType::TopK,
2608 "trietype0" => ValueType::Trie,
2610 "TSDB-TYPE" => ValueType::TimeSeries,
2612 "bloomfltr" => ValueType::BloomFilterValKey,
2614 s => ValueType::Unknown(s.to_string()),
2616 }
2617 }
2618}
2619
2620impl From<ValueType> for String {
2621 fn from(v: ValueType) -> Self {
2622 match v {
2623 ValueType::None => "none".to_string(),
2624 ValueType::String => "string".to_string(),
2625 ValueType::List => "list".to_string(),
2626 ValueType::Set => "set".to_string(),
2627 ValueType::ZSet => "zset".to_string(),
2628 ValueType::Hash => "hash".to_string(),
2629 ValueType::Stream => "stream".to_string(),
2630 ValueType::VectorSet => "vectorset".to_string(),
2631 ValueType::JSON => "ReJSON-RL".to_string(),
2633 ValueType::BloomFilterRedis => "MBbloom--".to_string(),
2635 ValueType::CuckooFilter => "MBbloomCF".to_string(),
2636 ValueType::TDigest => "TDIS-TYPE".to_string(),
2637 ValueType::TopK => "TopK-TYPE".to_string(),
2638 ValueType::CountMin => "CMSk-TYPE".to_string(),
2639 ValueType::Trie => "trietype0".to_string(),
2641 ValueType::TimeSeries => "TSDB-TYPE".to_string(),
2643 ValueType::BloomFilterValKey => "bloomfltr".to_string(),
2645 ValueType::Unknown(s) => s,
2647 }
2648 }
2649}
2650
2651impl FromRedisValue for ValueType {
2652 fn from_redis_value_ref(v: &Value) -> Result<Self, ParsingError> {
2653 match v {
2654 Value::SimpleString(s) => Ok(s.into()),
2655 _ => crate::errors::invalid_type_error!(v, "Value type should be a simple string"),
2656 }
2657 }
2658
2659 fn from_redis_value(v: Value) -> Result<Self, ParsingError> {
2660 match v {
2661 Value::SimpleString(s) => Ok(s.into()),
2662 _ => crate::errors::invalid_type_error!(v, "Value type should be a simple string"),
2663 }
2664 }
2665}
2666
2667#[derive(Debug, PartialEq, Clone)]
2669#[non_exhaustive]
2670pub enum IntegerReplyOrNoOp {
2671 IntegerReply(usize),
2673 NotExists,
2675 ExistsButNotRelevant,
2677}
2678
2679impl IntegerReplyOrNoOp {
2680 pub fn raw(&self) -> isize {
2682 match self {
2683 IntegerReplyOrNoOp::IntegerReply(s) => *s as isize,
2684 IntegerReplyOrNoOp::NotExists => -2,
2685 IntegerReplyOrNoOp::ExistsButNotRelevant => -1,
2686 }
2687 }
2688}
2689
2690impl FromRedisValue for IntegerReplyOrNoOp {
2691 fn from_redis_value_ref(v: &Value) -> Result<Self, ParsingError> {
2692 match v {
2693 Value::Int(s) => match s {
2694 -2 => Ok(IntegerReplyOrNoOp::NotExists),
2695 -1 => Ok(IntegerReplyOrNoOp::ExistsButNotRelevant),
2696 _ => Ok(IntegerReplyOrNoOp::IntegerReply(*s as usize)),
2697 },
2698 _ => crate::errors::invalid_type_error!(v, "Value should be an integer"),
2699 }
2700 }
2701
2702 fn from_redis_value(v: Value) -> Result<Self, ParsingError> {
2703 match v {
2704 Value::Int(s) => match s {
2705 -2 => Ok(IntegerReplyOrNoOp::NotExists),
2706 -1 => Ok(IntegerReplyOrNoOp::ExistsButNotRelevant),
2707 _ => Ok(IntegerReplyOrNoOp::IntegerReply(s as usize)),
2708 },
2709 _ => crate::errors::invalid_type_error!(v, "Value should be an integer"),
2710 }
2711 }
2712}
2713
2714impl PartialEq<isize> for IntegerReplyOrNoOp {
2715 fn eq(&self, other: &isize) -> bool {
2716 match self {
2717 IntegerReplyOrNoOp::IntegerReply(s) => *s as isize == *other,
2718 IntegerReplyOrNoOp::NotExists => *other == -2,
2719 IntegerReplyOrNoOp::ExistsButNotRelevant => *other == -1,
2720 }
2721 }
2722}
2723
2724impl PartialEq<usize> for IntegerReplyOrNoOp {
2725 fn eq(&self, other: &usize) -> bool {
2726 match self {
2727 IntegerReplyOrNoOp::IntegerReply(s) => *s == *other,
2728 _ => false,
2729 }
2730 }
2731}
2732
2733impl PartialEq<i32> for IntegerReplyOrNoOp {
2734 fn eq(&self, other: &i32) -> bool {
2735 match self {
2736 IntegerReplyOrNoOp::IntegerReply(s) => *s as i32 == *other,
2737 IntegerReplyOrNoOp::NotExists => *other == -2,
2738 IntegerReplyOrNoOp::ExistsButNotRelevant => *other == -1,
2739 }
2740 }
2741}
2742
2743impl PartialEq<u32> for IntegerReplyOrNoOp {
2744 fn eq(&self, other: &u32) -> bool {
2745 match self {
2746 IntegerReplyOrNoOp::IntegerReply(s) => *s as u32 == *other,
2747 _ => false,
2748 }
2749 }
2750}