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 self.buf.advance_mut(cnt);
956 }
957
958 fn chunk_mut(&mut self) -> &mut bytes::buf::UninitSlice {
959 self.buf.chunk_mut()
960 }
961
962 fn put<T: bytes::buf::Buf>(&mut self, src: T)
964 where
965 Self: Sized,
966 {
967 self.buf.put(src);
968 }
969
970 fn put_slice(&mut self, src: &[u8]) {
971 self.buf.put_slice(src);
972 }
973
974 fn put_bytes(&mut self, val: u8, cnt: usize) {
975 self.buf.put_bytes(val, cnt);
976 }
977 }
978 impl Drop for Wrapper<'_> {
979 fn drop(&mut self) {
980 self.writer.write_all(&self.buf).unwrap()
981 }
982 }
983
984 Wrapper {
985 buf: Vec::with_capacity(capacity),
986 writer: Box::new(self.writer_for_next_arg()),
987 }
988 }
989}
990
991impl RedisWrite for Vec<Vec<u8>> {
992 fn write_arg(&mut self, arg: &[u8]) {
993 self.push(arg.to_owned());
994 }
995
996 fn write_arg_fmt(&mut self, arg: impl fmt::Display) {
997 self.push(arg.to_string().into_bytes())
998 }
999
1000 fn writer_for_next_arg(&mut self) -> impl io::Write + '_ {
1001 self.push(Vec::new());
1002 self.last_mut().unwrap()
1003 }
1004
1005 fn reserve_space_for_args(&mut self, additional: impl IntoIterator<Item = usize>) {
1006 self.reserve(additional.into_iter().count());
1011 }
1012
1013 #[cfg(feature = "bytes")]
1014 fn bufmut_for_next_arg(&mut self, capacity: usize) -> impl bytes::BufMut + '_ {
1015 self.push(Vec::with_capacity(capacity));
1016 self.last_mut().unwrap()
1017 }
1018}
1019
1020pub trait ToSingleRedisArg: ToRedisArgs {}
1025
1026pub trait ToRedisArgs: Sized {
1030 fn to_redis_args(&self) -> Vec<Vec<u8>> {
1036 let mut out = Vec::new();
1037 self.write_redis_args(&mut out);
1038 out
1039 }
1040
1041 fn write_redis_args<W>(&self, out: &mut W)
1046 where
1047 W: ?Sized + RedisWrite;
1048
1049 fn describe_numeric_behavior(&self) -> NumericBehavior {
1054 NumericBehavior::NonNumeric
1055 }
1056
1057 fn num_of_args(&self) -> usize {
1064 1
1065 }
1066
1067 #[doc(hidden)]
1070 fn write_args_from_slice<W>(items: &[Self], out: &mut W)
1071 where
1072 W: ?Sized + RedisWrite,
1073 {
1074 Self::make_arg_iter_ref(items.iter(), out)
1075 }
1076
1077 #[doc(hidden)]
1080 fn make_arg_iter_ref<'a, I, W>(items: I, out: &mut W)
1081 where
1082 W: ?Sized + RedisWrite,
1083 I: Iterator<Item = &'a Self>,
1084 Self: 'a,
1085 {
1086 for item in items {
1087 item.write_redis_args(out);
1088 }
1089 }
1090
1091 #[doc(hidden)]
1092 fn is_single_vec_arg(items: &[Self]) -> bool {
1093 items.len() == 1 && items[0].num_of_args() <= 1
1094 }
1095}
1096
1097macro_rules! itoa_based_to_redis_impl {
1098 ($t:ty, $numeric:expr) => {
1099 impl ToRedisArgs for $t {
1100 fn write_redis_args<W>(&self, out: &mut W)
1101 where
1102 W: ?Sized + RedisWrite,
1103 {
1104 let mut buf = ::itoa::Buffer::new();
1105 let s = buf.format(*self);
1106 out.write_arg(s.as_bytes())
1107 }
1108
1109 fn describe_numeric_behavior(&self) -> NumericBehavior {
1110 $numeric
1111 }
1112 }
1113
1114 impl ToSingleRedisArg for $t {}
1115 };
1116}
1117
1118macro_rules! non_zero_itoa_based_to_redis_impl {
1119 ($t:ty, $numeric:expr) => {
1120 impl ToRedisArgs for $t {
1121 fn write_redis_args<W>(&self, out: &mut W)
1122 where
1123 W: ?Sized + RedisWrite,
1124 {
1125 let mut buf = ::itoa::Buffer::new();
1126 let s = buf.format(self.get());
1127 out.write_arg(s.as_bytes())
1128 }
1129
1130 fn describe_numeric_behavior(&self) -> NumericBehavior {
1131 $numeric
1132 }
1133 }
1134
1135 impl ToSingleRedisArg for $t {}
1136 };
1137}
1138
1139macro_rules! ryu_based_to_redis_impl {
1140 ($t:ty, $numeric:expr) => {
1141 impl ToRedisArgs for $t {
1142 fn write_redis_args<W>(&self, out: &mut W)
1143 where
1144 W: ?Sized + RedisWrite,
1145 {
1146 let mut buf = ::ryu::Buffer::new();
1147 let s = buf.format(*self);
1148 out.write_arg(s.as_bytes())
1149 }
1150
1151 fn describe_numeric_behavior(&self) -> NumericBehavior {
1152 $numeric
1153 }
1154 }
1155
1156 impl ToSingleRedisArg for $t {}
1157 };
1158}
1159
1160impl ToRedisArgs for u8 {
1161 fn write_redis_args<W>(&self, out: &mut W)
1162 where
1163 W: ?Sized + RedisWrite,
1164 {
1165 let mut buf = ::itoa::Buffer::new();
1166 let s = buf.format(*self);
1167 out.write_arg(s.as_bytes())
1168 }
1169
1170 fn write_args_from_slice<W>(items: &[u8], out: &mut W)
1171 where
1172 W: ?Sized + RedisWrite,
1173 {
1174 out.write_arg(items);
1175 }
1176
1177 fn is_single_vec_arg(_items: &[u8]) -> bool {
1178 true
1179 }
1180}
1181
1182impl ToSingleRedisArg for u8 {}
1183
1184itoa_based_to_redis_impl!(i8, NumericBehavior::NumberIsInteger);
1185itoa_based_to_redis_impl!(i16, NumericBehavior::NumberIsInteger);
1186itoa_based_to_redis_impl!(u16, NumericBehavior::NumberIsInteger);
1187itoa_based_to_redis_impl!(i32, NumericBehavior::NumberIsInteger);
1188itoa_based_to_redis_impl!(u32, NumericBehavior::NumberIsInteger);
1189itoa_based_to_redis_impl!(i64, NumericBehavior::NumberIsInteger);
1190itoa_based_to_redis_impl!(u64, NumericBehavior::NumberIsInteger);
1191itoa_based_to_redis_impl!(i128, NumericBehavior::NumberIsInteger);
1192itoa_based_to_redis_impl!(u128, NumericBehavior::NumberIsInteger);
1193itoa_based_to_redis_impl!(isize, NumericBehavior::NumberIsInteger);
1194itoa_based_to_redis_impl!(usize, NumericBehavior::NumberIsInteger);
1195
1196non_zero_itoa_based_to_redis_impl!(core::num::NonZeroU8, NumericBehavior::NumberIsInteger);
1197non_zero_itoa_based_to_redis_impl!(core::num::NonZeroI8, NumericBehavior::NumberIsInteger);
1198non_zero_itoa_based_to_redis_impl!(core::num::NonZeroU16, NumericBehavior::NumberIsInteger);
1199non_zero_itoa_based_to_redis_impl!(core::num::NonZeroI16, NumericBehavior::NumberIsInteger);
1200non_zero_itoa_based_to_redis_impl!(core::num::NonZeroU32, NumericBehavior::NumberIsInteger);
1201non_zero_itoa_based_to_redis_impl!(core::num::NonZeroI32, NumericBehavior::NumberIsInteger);
1202non_zero_itoa_based_to_redis_impl!(core::num::NonZeroU64, NumericBehavior::NumberIsInteger);
1203non_zero_itoa_based_to_redis_impl!(core::num::NonZeroI64, NumericBehavior::NumberIsInteger);
1204non_zero_itoa_based_to_redis_impl!(core::num::NonZeroU128, NumericBehavior::NumberIsInteger);
1205non_zero_itoa_based_to_redis_impl!(core::num::NonZeroI128, NumericBehavior::NumberIsInteger);
1206non_zero_itoa_based_to_redis_impl!(core::num::NonZeroUsize, NumericBehavior::NumberIsInteger);
1207non_zero_itoa_based_to_redis_impl!(core::num::NonZeroIsize, NumericBehavior::NumberIsInteger);
1208
1209ryu_based_to_redis_impl!(f32, NumericBehavior::NumberIsFloat);
1210ryu_based_to_redis_impl!(f64, NumericBehavior::NumberIsFloat);
1211
1212#[cfg(any(
1213 feature = "rust_decimal",
1214 feature = "bigdecimal",
1215 feature = "num-bigint"
1216))]
1217macro_rules! bignum_to_redis_impl {
1218 ($t:ty) => {
1219 impl ToRedisArgs for $t {
1220 fn write_redis_args<W>(&self, out: &mut W)
1221 where
1222 W: ?Sized + RedisWrite,
1223 {
1224 out.write_arg(&self.to_string().into_bytes())
1225 }
1226 }
1227
1228 impl ToSingleRedisArg for $t {}
1229 };
1230}
1231
1232#[cfg(feature = "rust_decimal")]
1233bignum_to_redis_impl!(rust_decimal::Decimal);
1234#[cfg(feature = "bigdecimal")]
1235bignum_to_redis_impl!(bigdecimal::BigDecimal);
1236#[cfg(feature = "num-bigint")]
1237bignum_to_redis_impl!(num_bigint::BigInt);
1238#[cfg(feature = "num-bigint")]
1239bignum_to_redis_impl!(num_bigint::BigUint);
1240
1241impl ToRedisArgs for bool {
1242 fn write_redis_args<W>(&self, out: &mut W)
1243 where
1244 W: ?Sized + RedisWrite,
1245 {
1246 out.write_arg(if *self { b"1" } else { b"0" })
1247 }
1248}
1249
1250impl ToSingleRedisArg for bool {}
1251
1252impl ToRedisArgs for String {
1253 fn write_redis_args<W>(&self, out: &mut W)
1254 where
1255 W: ?Sized + RedisWrite,
1256 {
1257 out.write_arg(self.as_bytes())
1258 }
1259}
1260impl ToSingleRedisArg for String {}
1261
1262impl ToRedisArgs for &str {
1263 fn write_redis_args<W>(&self, out: &mut W)
1264 where
1265 W: ?Sized + RedisWrite,
1266 {
1267 out.write_arg(self.as_bytes())
1268 }
1269}
1270
1271impl ToSingleRedisArg for &str {}
1272
1273impl<'a, T> ToRedisArgs for Cow<'a, T>
1274where
1275 T: ToOwned + ?Sized,
1276 &'a T: ToRedisArgs,
1277 T::Owned: ToRedisArgs,
1278{
1279 fn write_redis_args<W>(&self, out: &mut W)
1280 where
1281 W: ?Sized + RedisWrite,
1282 {
1283 match self {
1284 Cow::Borrowed(inner) => inner.write_redis_args(out),
1285 Cow::Owned(inner) => inner.write_redis_args(out),
1286 }
1287 }
1288}
1289
1290impl<'a, T> ToSingleRedisArg for Cow<'a, T>
1291where
1292 T: ToOwned + ?Sized,
1293 &'a T: ToSingleRedisArg,
1294 T::Owned: ToSingleRedisArg,
1295{
1296}
1297
1298impl<T: ToRedisArgs> ToRedisArgs for Option<T> {
1299 fn write_redis_args<W>(&self, out: &mut W)
1300 where
1301 W: ?Sized + RedisWrite,
1302 {
1303 if let Some(ref x) = *self {
1304 x.write_redis_args(out);
1305 }
1306 }
1307
1308 fn describe_numeric_behavior(&self) -> NumericBehavior {
1309 match *self {
1310 Some(ref x) => x.describe_numeric_behavior(),
1311 None => NumericBehavior::NonNumeric,
1312 }
1313 }
1314
1315 fn num_of_args(&self) -> usize {
1316 match *self {
1317 Some(ref x) => x.num_of_args(),
1318 None => 0,
1319 }
1320 }
1321}
1322
1323macro_rules! impl_write_redis_args_for_collection {
1324 ($type:ty) => {
1325 impl<'a, T> ToRedisArgs for $type
1326 where
1327 T: ToRedisArgs,
1328 {
1329 #[inline]
1330 fn write_redis_args<W>(&self, out: &mut W)
1331 where
1332 W: ?Sized + RedisWrite,
1333 {
1334 ToRedisArgs::write_args_from_slice(self, out)
1335 }
1336
1337 fn num_of_args(&self) -> usize {
1338 if ToRedisArgs::is_single_vec_arg(&self[..]) {
1339 return 1;
1340 }
1341 if self.len() == 1 {
1342 self[0].num_of_args()
1343 } else {
1344 self.len()
1345 }
1346 }
1347
1348 fn describe_numeric_behavior(&self) -> NumericBehavior {
1349 NumericBehavior::NonNumeric
1350 }
1351 }
1352 };
1353}
1354
1355macro_rules! deref_to_write_redis_args_impl {
1356 ($type:ty) => {
1357 impl<'a, T> ToRedisArgs for $type
1358 where
1359 T: ToRedisArgs,
1360 {
1361 #[inline]
1362 fn write_redis_args<W>(&self, out: &mut W)
1363 where
1364 W: ?Sized + RedisWrite,
1365 {
1366 (**self).write_redis_args(out)
1367 }
1368
1369 fn num_of_args(&self) -> usize {
1370 (**self).num_of_args()
1371 }
1372
1373 fn describe_numeric_behavior(&self) -> NumericBehavior {
1374 (**self).describe_numeric_behavior()
1375 }
1376 }
1377
1378 impl<'a, T> ToSingleRedisArg for $type where T: ToSingleRedisArg {}
1379 };
1380}
1381
1382deref_to_write_redis_args_impl! {&'a T}
1383deref_to_write_redis_args_impl! {&'a mut T}
1384deref_to_write_redis_args_impl! {Box<T>}
1385deref_to_write_redis_args_impl! {std::sync::Arc<T>}
1386deref_to_write_redis_args_impl! {std::rc::Rc<T>}
1387impl_write_redis_args_for_collection! {&'a [T]}
1388impl_write_redis_args_for_collection! {&'a mut [T]}
1389impl_write_redis_args_for_collection! {Box<[T]>}
1390impl_write_redis_args_for_collection! {std::sync::Arc<[T]>}
1391impl_write_redis_args_for_collection! {std::rc::Rc<[T]>}
1392impl_write_redis_args_for_collection! {Vec<T>}
1393impl ToSingleRedisArg for &[u8] {}
1394impl ToSingleRedisArg for &mut [u8] {}
1395impl ToSingleRedisArg for Vec<u8> {}
1396impl ToSingleRedisArg for Box<[u8]> {}
1397impl ToSingleRedisArg for std::rc::Rc<[u8]> {}
1398impl ToSingleRedisArg for std::sync::Arc<[u8]> {}
1399
1400macro_rules! impl_to_redis_args_for_set {
1404 (for <$($TypeParam:ident),+> $SetType:ty, where ($($WhereClause:tt)+) ) => {
1405 impl< $($TypeParam),+ > ToRedisArgs for $SetType
1406 where
1407 $($WhereClause)+
1408 {
1409 fn write_redis_args<W>(&self, out: &mut W)
1410 where
1411 W: ?Sized + RedisWrite,
1412 {
1413 ToRedisArgs::make_arg_iter_ref(self.iter(), out)
1414 }
1415
1416 fn num_of_args(&self) -> usize {
1417 self.len()
1418 }
1419 }
1420 };
1421}
1422
1423impl_to_redis_args_for_set!(
1424 for <T, S> std::collections::HashSet<T, S>,
1425 where (T: ToRedisArgs + Hash + Eq)
1426);
1427
1428impl_to_redis_args_for_set!(
1429 for <T> std::collections::BTreeSet<T>,
1430 where (T: ToRedisArgs + Hash + Eq + Ord)
1431);
1432
1433#[cfg(feature = "hashbrown")]
1434impl_to_redis_args_for_set!(
1435 for <T, S> hashbrown::HashSet<T, S>,
1436 where (T: ToRedisArgs + Hash + Eq)
1437);
1438
1439#[cfg(feature = "ahash")]
1440impl_to_redis_args_for_set!(
1441 for <T, S> ahash::AHashSet<T, S>,
1442 where (T: ToRedisArgs + Hash + Eq)
1443);
1444
1445macro_rules! impl_to_redis_args_for_map {
1449 (
1450 $(#[$meta:meta])*
1451 for <$($TypeParam:ident),+> $MapType:ty,
1452 where ($($WhereClause:tt)+)
1453 ) => {
1454 $(#[$meta])*
1455 impl< $($TypeParam),+ > ToRedisArgs for $MapType
1456 where
1457 $($WhereClause)+
1458 {
1459 fn write_redis_args<W>(&self, out: &mut W)
1460 where
1461 W: ?Sized + RedisWrite,
1462 {
1463 for (key, value) in self {
1464 assert!(key.num_of_args() <= 1 && value.num_of_args() <= 1);
1466 key.write_redis_args(out);
1467 value.write_redis_args(out);
1468 }
1469 }
1470
1471 fn num_of_args(&self) -> usize {
1472 self.len()
1473 }
1474 }
1475 };
1476}
1477
1478impl_to_redis_args_for_map!(
1479 for <K, V, S> std::collections::HashMap<K, V, S>,
1480 where (K: ToRedisArgs + Hash + Eq + Ord, V: ToRedisArgs)
1481);
1482
1483impl_to_redis_args_for_map!(
1484 for <K, V> std::collections::BTreeMap<K, V>,
1486 where (K: ToRedisArgs + Hash + Eq + Ord, V: ToRedisArgs)
1487);
1488
1489#[cfg(feature = "hashbrown")]
1490impl_to_redis_args_for_map!(
1491 for <K, V, S> hashbrown::HashMap<K, V, S>,
1492 where (K: ToRedisArgs + Hash + Eq + Ord, V: ToRedisArgs)
1493);
1494
1495#[cfg(feature = "ahash")]
1496impl_to_redis_args_for_map!(
1497 for <K, V, S> ahash::AHashMap<K, V, S>,
1498 where (K: ToRedisArgs + Hash + Eq + Ord, V: ToRedisArgs)
1499);
1500
1501macro_rules! to_redis_args_for_tuple {
1502 () => ();
1503 ($(#[$meta:meta],)*$($name:ident,)+) => (
1504 $(#[$meta])*
1505 impl<$($name: ToRedisArgs),*> ToRedisArgs for ($($name,)*) {
1506 #[allow(non_snake_case, unused_variables)]
1509 fn write_redis_args<W>(&self, out: &mut W) where W: ?Sized + RedisWrite {
1510 let ($(ref $name,)*) = *self;
1511 $($name.write_redis_args(out);)*
1512 }
1513
1514 #[allow(non_snake_case, unused_variables)]
1515 fn num_of_args(&self) -> usize {
1516 let mut n: usize = 0;
1517 $(let $name = (); n += 1;)*
1518 n
1519 }
1520 }
1521 )
1522}
1523
1524to_redis_args_for_tuple! { #[cfg_attr(docsrs, doc(fake_variadic))], #[doc = "This trait is implemented for tuples up to 12 items long."], T, }
1525to_redis_args_for_tuple! { #[doc(hidden)], T1, T2, }
1526to_redis_args_for_tuple! { #[doc(hidden)], T1, T2, T3, }
1527to_redis_args_for_tuple! { #[doc(hidden)], T1, T2, T3, T4, }
1528to_redis_args_for_tuple! { #[doc(hidden)], T1, T2, T3, T4, T5, }
1529to_redis_args_for_tuple! { #[doc(hidden)], T1, T2, T3, T4, T5, T6, }
1530to_redis_args_for_tuple! { #[doc(hidden)], T1, T2, T3, T4, T5, T6, T7, }
1531to_redis_args_for_tuple! { #[doc(hidden)], T1, T2, T3, T4, T5, T6, T7, T8, }
1532to_redis_args_for_tuple! { #[doc(hidden)], T1, T2, T3, T4, T5, T6, T7, T8, T9, }
1533to_redis_args_for_tuple! { #[doc(hidden)], T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, }
1534to_redis_args_for_tuple! { #[doc(hidden)], T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, }
1535to_redis_args_for_tuple! { #[doc(hidden)], T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, }
1536
1537impl<T: ToRedisArgs, const N: usize> ToRedisArgs for &[T; N] {
1538 fn write_redis_args<W>(&self, out: &mut W)
1539 where
1540 W: ?Sized + RedisWrite,
1541 {
1542 ToRedisArgs::write_args_from_slice(self.as_slice(), out)
1543 }
1544
1545 fn num_of_args(&self) -> usize {
1546 if ToRedisArgs::is_single_vec_arg(&self[..]) {
1547 return 1;
1548 }
1549 if self.len() == 1 {
1550 self[0].num_of_args()
1551 } else {
1552 self.len()
1553 }
1554 }
1555}
1556impl<const N: usize> ToSingleRedisArg for &[u8; N] {}
1557
1558fn vec_to_array<T, const N: usize>(
1559 items: Vec<T>,
1560 original_value: &Value,
1561) -> Result<[T; N], ParsingError> {
1562 match items.try_into() {
1563 Ok(array) => Ok(array),
1564 Err(items) => {
1565 let msg = format!(
1566 "Response has wrong dimension, expected {N}, got {}",
1567 items.len()
1568 );
1569 crate::errors::invalid_type_error!(original_value, msg)
1570 }
1571 }
1572}
1573
1574impl<T: FromRedisValue, const N: usize> FromRedisValue for [T; N] {
1575 fn from_redis_value_ref(value: &Value) -> Result<[T; N], ParsingError> {
1576 match *value {
1577 Value::BulkString(ref bytes) => match FromRedisValue::from_byte_slice(bytes) {
1578 Some(items) => vec_to_array(items, value),
1579 None => {
1580 let msg = format!(
1581 "Conversion to Array[{}; {N}] failed",
1582 std::any::type_name::<T>()
1583 );
1584 crate::errors::invalid_type_error!(value, msg)
1585 }
1586 },
1587 Value::Array(ref items) => {
1588 let items = FromRedisValue::from_redis_value_refs(items)?;
1589 vec_to_array(items, value)
1590 }
1591 Value::Nil => vec_to_array(vec![], value),
1592 _ => crate::errors::invalid_type_error!(value, "Response type not array compatible"),
1593 }
1594 }
1595
1596 fn from_redis_value(v: Value) -> Result<Self, ParsingError> {
1597 Self::from_redis_value_ref(&v)
1598 }
1599}
1600
1601pub trait FromRedisValue: Sized {
1615 fn from_redis_value_ref(v: &Value) -> Result<Self, ParsingError> {
1619 Self::from_redis_value(v.clone())
1623 }
1624
1625 fn from_redis_value(v: Value) -> Result<Self, ParsingError>;
1629
1630 fn from_redis_value_refs(items: &[Value]) -> Result<Vec<Self>, ParsingError> {
1634 items
1635 .iter()
1636 .map(FromRedisValue::from_redis_value_ref)
1637 .collect()
1638 }
1639
1640 fn from_redis_values(items: Vec<Value>) -> Result<Vec<Self>, ParsingError> {
1643 items
1644 .into_iter()
1645 .map(FromRedisValue::from_redis_value)
1646 .collect()
1647 }
1648
1649 fn from_each_redis_values(items: Vec<Value>) -> Vec<Result<Self, ParsingError>> {
1652 items
1653 .into_iter()
1654 .map(FromRedisValue::from_redis_value)
1655 .collect()
1656 }
1657
1658 fn from_byte_slice(_vec: &[u8]) -> Option<Vec<Self>> {
1660 Self::from_redis_value(Value::BulkString(_vec.into()))
1661 .map(|rv| vec![rv])
1662 .ok()
1663 }
1664
1665 fn from_byte_vec(_vec: Vec<u8>) -> Result<Vec<Self>, ParsingError> {
1667 Self::from_redis_value(Value::BulkString(_vec)).map(|rv| vec![rv])
1668 }
1669}
1670
1671fn get_inner_value(v: &Value) -> &Value {
1672 if let Value::Attribute {
1673 data,
1674 attributes: _,
1675 } = v
1676 {
1677 data.as_ref()
1678 } else {
1679 v
1680 }
1681}
1682
1683fn get_owned_inner_value(v: Value) -> Value {
1684 if let Value::Attribute {
1685 data,
1686 attributes: _,
1687 } = v
1688 {
1689 *data
1690 } else {
1691 v
1692 }
1693}
1694
1695macro_rules! from_redis_value_for_num_internal {
1696 ($t:ty, $v:expr) => {{
1697 let v = if let Value::Attribute {
1698 data,
1699 attributes: _,
1700 } = $v
1701 {
1702 data
1703 } else {
1704 $v
1705 };
1706 match *v {
1707 Value::Int(val) => Ok(val as $t),
1708 Value::SimpleString(ref s) => match s.parse::<$t>() {
1709 Ok(rv) => Ok(rv),
1710 Err(_) => crate::errors::invalid_type_error!(v, "Could not convert from string."),
1711 },
1712 Value::BulkString(ref bytes) => match from_utf8(bytes)?.parse::<$t>() {
1713 Ok(rv) => Ok(rv),
1714 Err(_) => crate::errors::invalid_type_error!(v, "Could not convert from string."),
1715 },
1716 Value::Double(val) => Ok(val as $t),
1717 _ => crate::errors::invalid_type_error!(v, "Response type not convertible to numeric."),
1718 }
1719 }};
1720}
1721
1722macro_rules! from_redis_value_for_num {
1723 ($t:ty) => {
1724 impl FromRedisValue for $t {
1725 fn from_redis_value_ref(v: &Value) -> Result<$t, ParsingError> {
1726 from_redis_value_for_num_internal!($t, v)
1727 }
1728
1729 fn from_redis_value(v: Value) -> Result<Self, ParsingError> {
1730 Self::from_redis_value_ref(&v)
1731 }
1732 }
1733 };
1734}
1735
1736impl FromRedisValue for u8 {
1737 fn from_redis_value_ref(v: &Value) -> Result<u8, ParsingError> {
1738 from_redis_value_for_num_internal!(u8, v)
1739 }
1740
1741 fn from_redis_value(v: Value) -> Result<Self, ParsingError> {
1742 Self::from_redis_value_ref(&v)
1743 }
1744
1745 fn from_byte_slice(vec: &[u8]) -> Option<Vec<u8>> {
1747 Some(vec.to_vec())
1748 }
1749 fn from_byte_vec(vec: Vec<u8>) -> Result<Vec<u8>, ParsingError> {
1750 Ok(vec)
1751 }
1752}
1753
1754from_redis_value_for_num!(i8);
1755from_redis_value_for_num!(i16);
1756from_redis_value_for_num!(u16);
1757from_redis_value_for_num!(i32);
1758from_redis_value_for_num!(u32);
1759from_redis_value_for_num!(i64);
1760from_redis_value_for_num!(u64);
1761from_redis_value_for_num!(i128);
1762from_redis_value_for_num!(u128);
1763from_redis_value_for_num!(f32);
1764from_redis_value_for_num!(f64);
1765from_redis_value_for_num!(isize);
1766from_redis_value_for_num!(usize);
1767
1768#[cfg(any(
1769 feature = "rust_decimal",
1770 feature = "bigdecimal",
1771 feature = "num-bigint"
1772))]
1773macro_rules! from_redis_value_for_bignum_internal {
1774 ($t:ty, $v:expr) => {{
1775 let v = $v;
1776 match *v {
1777 Value::Int(val) => <$t>::try_from(val).map_err(|_| {
1778 crate::errors::invalid_type_error_inner!(v, "Could not convert from integer.")
1779 }),
1780 Value::SimpleString(ref s) => match s.parse::<$t>() {
1781 Ok(rv) => Ok(rv),
1782 Err(_) => crate::errors::invalid_type_error!(v, "Could not convert from string."),
1783 },
1784 Value::BulkString(ref bytes) => match from_utf8(bytes)?.parse::<$t>() {
1785 Ok(rv) => Ok(rv),
1786 Err(_) => crate::errors::invalid_type_error!(v, "Could not convert from string."),
1787 },
1788 _ => crate::errors::invalid_type_error!(v, "Response type not convertible to numeric."),
1789 }
1790 }};
1791}
1792
1793#[cfg(any(
1794 feature = "rust_decimal",
1795 feature = "bigdecimal",
1796 feature = "num-bigint"
1797))]
1798macro_rules! from_redis_value_for_bignum {
1799 ($t:ty) => {
1800 impl FromRedisValue for $t {
1801 fn from_redis_value_ref(v: &Value) -> Result<$t, ParsingError> {
1802 from_redis_value_for_bignum_internal!($t, v)
1803 }
1804
1805 fn from_redis_value(v: Value) -> Result<Self, ParsingError> {
1806 Self::from_redis_value_ref(&v)
1807 }
1808 }
1809 };
1810}
1811
1812#[cfg(feature = "rust_decimal")]
1813from_redis_value_for_bignum!(rust_decimal::Decimal);
1814#[cfg(feature = "bigdecimal")]
1815from_redis_value_for_bignum!(bigdecimal::BigDecimal);
1816#[cfg(feature = "num-bigint")]
1817from_redis_value_for_bignum!(num_bigint::BigInt);
1818#[cfg(feature = "num-bigint")]
1819from_redis_value_for_bignum!(num_bigint::BigUint);
1820
1821impl FromRedisValue for bool {
1822 fn from_redis_value_ref(v: &Value) -> Result<bool, ParsingError> {
1823 let v = get_inner_value(v);
1824 match *v {
1825 Value::Nil => Ok(false),
1826 Value::Int(val) => Ok(val != 0),
1827 Value::SimpleString(ref s) => {
1828 if &s[..] == "1" {
1829 Ok(true)
1830 } else if &s[..] == "0" {
1831 Ok(false)
1832 } else {
1833 crate::errors::invalid_type_error!(v, "Response status not valid boolean");
1834 }
1835 }
1836 Value::BulkString(ref bytes) => {
1837 if bytes == b"1" {
1838 Ok(true)
1839 } else if bytes == b"0" {
1840 Ok(false)
1841 } else {
1842 crate::errors::invalid_type_error!(v, "Response type not bool compatible.");
1843 }
1844 }
1845 Value::Boolean(b) => Ok(b),
1846 Value::Okay => Ok(true),
1847 _ => crate::errors::invalid_type_error!(v, "Response type not bool compatible."),
1848 }
1849 }
1850
1851 fn from_redis_value(v: Value) -> Result<Self, ParsingError> {
1852 Self::from_redis_value_ref(&v)
1853 }
1854}
1855
1856impl FromRedisValue for CString {
1857 fn from_redis_value_ref(v: &Value) -> Result<CString, ParsingError> {
1858 let v = get_inner_value(v);
1859 match *v {
1860 Value::BulkString(ref bytes) => Ok(CString::new(bytes.as_slice())?),
1861 Value::Okay => Ok(CString::new("OK")?),
1862 Value::SimpleString(ref val) => Ok(CString::new(val.as_bytes())?),
1863 _ => crate::errors::invalid_type_error!(v, "Response type not CString compatible."),
1864 }
1865 }
1866 fn from_redis_value(v: Value) -> Result<CString, ParsingError> {
1867 let v = get_owned_inner_value(v);
1868 match v {
1869 Value::BulkString(bytes) => Ok(CString::new(bytes)?),
1870 Value::Okay => Ok(CString::new("OK")?),
1871 Value::SimpleString(val) => Ok(CString::new(val)?),
1872 _ => crate::errors::invalid_type_error!(v, "Response type not CString compatible."),
1873 }
1874 }
1875}
1876
1877impl FromRedisValue for String {
1878 fn from_redis_value_ref(v: &Value) -> Result<Self, ParsingError> {
1879 let v = get_inner_value(v);
1880 match *v {
1881 Value::BulkString(ref bytes) => Ok(from_utf8(bytes)?.to_string()),
1882 Value::Okay => Ok("OK".to_string()),
1883 Value::SimpleString(ref val) => Ok(val.to_string()),
1884 Value::VerbatimString {
1885 format: _,
1886 ref text,
1887 } => Ok(text.to_string()),
1888 Value::Double(ref val) => Ok(val.to_string()),
1889 Value::Int(val) => Ok(val.to_string()),
1890 _ => crate::errors::invalid_type_error!(v, "Response type not string compatible."),
1891 }
1892 }
1893
1894 fn from_redis_value(v: Value) -> Result<Self, ParsingError> {
1895 let v = get_owned_inner_value(v);
1896 match v {
1897 Value::BulkString(bytes) => Ok(Self::from_utf8(bytes)?),
1898 Value::Okay => Ok("OK".to_string()),
1899 Value::SimpleString(val) => Ok(val),
1900 Value::VerbatimString { format: _, text } => Ok(text),
1901 Value::Double(val) => Ok(val.to_string()),
1902 Value::Int(val) => Ok(val.to_string()),
1903 _ => crate::errors::invalid_type_error!(v, "Response type not string compatible."),
1904 }
1905 }
1906}
1907
1908macro_rules! pointer_from_redis_value_impl {
1909 (
1910 $(#[$attr:meta])*
1911 $id:ident, $ty:ty, $func:expr
1912 ) => {
1913 $(#[$attr])*
1914 impl<$id: FromRedisValue> FromRedisValue for $ty {
1915 fn from_redis_value_ref(v: &Value) -> Result<Self, ParsingError>
1916 {
1917 FromRedisValue::from_redis_value_ref(v).map($func)
1918 }
1919
1920 fn from_redis_value(v: Value) -> Result<Self, ParsingError>{
1921 FromRedisValue::from_redis_value(v).map($func)
1922 }
1923 }
1924 }
1925}
1926
1927pointer_from_redis_value_impl!(T, Box<T>, Box::new);
1928pointer_from_redis_value_impl!(T, std::sync::Arc<T>, std::sync::Arc::new);
1929pointer_from_redis_value_impl!(T, std::rc::Rc<T>, std::rc::Rc::new);
1930
1931macro_rules! from_vec_from_redis_value {
1936 (<$T:ident> $Type:ty) => {
1937 from_vec_from_redis_value!(<$T> $Type; Into::into);
1938 };
1939
1940 (<$T:ident> $Type:ty; $convert:expr) => {
1941 impl<$T: FromRedisValue> FromRedisValue for $Type {
1942 fn from_redis_value_ref(v: &Value) -> Result<$Type, ParsingError> {
1943 match v {
1944 Value::BulkString(bytes) => match FromRedisValue::from_byte_slice(bytes) {
1947 Some(x) => Ok($convert(x)),
1948 None => crate::errors::invalid_type_error!(
1949 v,
1950 format!("Conversion to {} failed.", std::any::type_name::<$Type>())
1951 ),
1952 },
1953 Value::Array(items) => FromRedisValue::from_redis_value_refs(items).map($convert),
1954 Value::Set(ref items) => FromRedisValue::from_redis_value_refs(items).map($convert),
1955 Value::Map(ref items) => {
1956 let mut n: Vec<T> = vec![];
1957 for item in items {
1958 match FromRedisValue::from_redis_value_ref(&Value::Map(vec![item.clone()])) {
1959 Ok(v) => {
1960 n.push(v);
1961 }
1962 Err(e) => {
1963 return Err(e);
1964 }
1965 }
1966 }
1967 Ok($convert(n))
1968 }
1969 Value::Nil => Ok($convert(Vec::new())),
1970 _ => crate::errors::invalid_type_error!(v, "Response type not vector compatible."),
1971 }
1972 }
1973 fn from_redis_value(v: Value) -> Result<$Type, ParsingError> {
1974 match v {
1975 Value::BulkString(bytes) => FromRedisValue::from_byte_vec(bytes).map($convert),
1979 Value::Array(items) => FromRedisValue::from_redis_values(items).map($convert),
1980 Value::Set(items) => FromRedisValue::from_redis_values(items).map($convert),
1981 Value::Map(items) => {
1982 let mut n: Vec<T> = vec![];
1983 for item in items {
1984 match FromRedisValue::from_redis_value(Value::Map(vec![item])) {
1985 Ok(v) => {
1986 n.push(v);
1987 }
1988 Err(e) => {
1989 return Err(e);
1990 }
1991 }
1992 }
1993 Ok($convert(n))
1994 }
1995 Value::Nil => Ok($convert(Vec::new())),
1996 _ => crate::errors::invalid_type_error!(v, "Response type not vector compatible."),
1997 }
1998 }
1999 }
2000 };
2001}
2002
2003from_vec_from_redis_value!(<T> Vec<T>);
2004from_vec_from_redis_value!(<T> std::sync::Arc<[T]>);
2005from_vec_from_redis_value!(<T> Box<[T]>; Vec::into_boxed_slice);
2006
2007macro_rules! impl_from_redis_value_for_map {
2008 (for <$($TypeParam:ident),+> $MapType:ty, where ($($WhereClause:tt)+)) => {
2009 impl< $($TypeParam),+ > FromRedisValue for $MapType
2010 where
2011 $($WhereClause)+
2012 {
2013 fn from_redis_value_ref(v: &Value) -> Result<$MapType, ParsingError> {
2014 let v = get_inner_value(v);
2015 match *v {
2016 Value::Nil => Ok(Default::default()),
2017 _ => v
2018 .as_map_iter()
2019 .ok_or_else(|| crate::errors::invalid_type_error_inner!(v, "Response type not map compatible"))?
2020 .map(|(k, v)| {
2021 Ok((from_redis_value_ref(k)?, from_redis_value_ref(v)?))
2022 })
2023 .collect(),
2024 }
2025 }
2026
2027 fn from_redis_value(v: Value) -> Result<$MapType, ParsingError> {
2028 let v = get_owned_inner_value(v);
2029 match v {
2030 Value::Nil => Ok(Default::default()),
2031 _ => v
2032 .into_map_iter()
2033 .map_err(|v| crate::errors::invalid_type_error_inner!(v, "Response type not map compatible"))?
2034 .map(|(k, v)| {
2035 Ok((from_redis_value(k)?, from_redis_value(v)?))
2036 })
2037 .collect(),
2038 }
2039 }
2040 }
2041 };
2042}
2043
2044impl_from_redis_value_for_map!(
2045 for <K, V, S> std::collections::HashMap<K, V, S>,
2046 where (K: FromRedisValue + Eq + Hash, V: FromRedisValue, S: BuildHasher + Default)
2047);
2048
2049impl_from_redis_value_for_map!(
2050 for <K, V> std::collections::BTreeMap<K, V>,
2051 where (K: FromRedisValue + Eq + Hash + Ord, V: FromRedisValue)
2052);
2053
2054#[cfg(feature = "hashbrown")]
2055impl_from_redis_value_for_map!(
2056 for <K, V, S> hashbrown::HashMap<K, V, S>,
2057 where (K: FromRedisValue + Eq + Hash, V: FromRedisValue, S: BuildHasher + Default)
2058);
2059
2060#[cfg(feature = "ahash")]
2062impl_from_redis_value_for_map!(
2063 for <K, V> ahash::AHashMap<K, V>,
2064 where (K: FromRedisValue + Eq + Hash, V: FromRedisValue)
2065);
2066
2067macro_rules! impl_from_redis_value_for_set {
2068 (for <$($TypeParam:ident),+> $SetType:ty, where ($($WhereClause:tt)+)) => {
2069 impl< $($TypeParam),+ > FromRedisValue for $SetType
2070 where
2071 $($WhereClause)+
2072 {
2073 fn from_redis_value_ref(v: &Value) -> Result<$SetType, ParsingError> {
2074 let v = get_inner_value(v);
2075 let items = v
2076 .as_sequence()
2077 .ok_or_else(|| crate::errors::invalid_type_error_inner!(v, "Response type not map compatible"))?;
2078 items.iter().map(|item| from_redis_value_ref(item)).collect()
2079 }
2080
2081 fn from_redis_value(v: Value) -> Result<$SetType, ParsingError> {
2082 let v = get_owned_inner_value(v);
2083 let items = v
2084 .into_sequence()
2085 .map_err(|v| crate::errors::invalid_type_error_inner!(v, "Response type not map compatible"))?;
2086 items
2087 .into_iter()
2088 .map(|item| from_redis_value(item))
2089 .collect()
2090 }
2091 }
2092 };
2093}
2094
2095impl_from_redis_value_for_set!(
2096 for <T, S> std::collections::HashSet<T, S>,
2097 where (T: FromRedisValue + Eq + Hash, S: BuildHasher + Default)
2098);
2099
2100impl_from_redis_value_for_set!(
2101 for <T> std::collections::BTreeSet<T>,
2102 where (T: FromRedisValue + Eq + Ord)
2103);
2104
2105#[cfg(feature = "hashbrown")]
2106impl_from_redis_value_for_set!(
2107 for <T, S> hashbrown::HashSet<T, S>,
2108 where (T: FromRedisValue + Eq + Hash, S: BuildHasher + Default)
2109);
2110
2111#[cfg(feature = "ahash")]
2113impl_from_redis_value_for_set!(
2114 for <T> ahash::AHashSet<T>,
2115 where (T: FromRedisValue + Eq + Hash)
2116);
2117
2118impl FromRedisValue for Value {
2119 fn from_redis_value_ref(v: &Value) -> Result<Value, ParsingError> {
2120 Ok(v.clone())
2121 }
2122
2123 fn from_redis_value(v: Value) -> Result<Self, ParsingError> {
2124 Ok(v)
2125 }
2126}
2127
2128impl FromRedisValue for () {
2129 fn from_redis_value_ref(v: &Value) -> Result<(), ParsingError> {
2130 match v {
2131 Value::ServerError(err) => Err(ParsingError::from(err.to_string())),
2132 _ => Ok(()),
2133 }
2134 }
2135
2136 fn from_redis_value(v: Value) -> Result<(), ParsingError> {
2137 Self::from_redis_value_ref(&v)
2138 }
2139}
2140
2141macro_rules! from_redis_value_for_tuple {
2142 () => ();
2143 ($(#[$meta:meta],)*$($name:ident,)+) => (
2144 $(#[$meta])*
2145 impl<$($name: FromRedisValue),*> FromRedisValue for ($($name,)*) {
2146 #[allow(non_snake_case, unused_variables)]
2149 fn from_redis_value_ref(v: &Value) -> Result<($($name,)*), ParsingError> {
2150 let v = get_inner_value(v);
2151 let mut n = 0;
2153 $(let $name = (); n += 1;)*
2154
2155 match *v {
2156 Value::Array(ref items) => {
2157 if items.len() != n {
2158 crate::errors::invalid_type_error!(v, "Array response of wrong dimension")
2159 }
2160
2161 let mut i = 0;
2163 Ok(($({let $name = (); from_redis_value_ref(
2164 &items[{ i += 1; i - 1 }])?},)*))
2165 }
2166
2167 Value::Set(ref items) => {
2168 if items.len() != n {
2169 crate::errors::invalid_type_error!(v, "Set response of wrong dimension")
2170 }
2171
2172 let mut i = 0;
2174 Ok(($({let $name = (); from_redis_value_ref(
2175 &items[{ i += 1; i - 1 }])?},)*))
2176 }
2177
2178 Value::Map(ref items) => {
2179 if n != items.len() * 2 {
2180 crate::errors::invalid_type_error!(v, "Map response of wrong dimension")
2181 }
2182
2183 let mut flatten_items = items.iter().map(|(a,b)|[a,b]).flatten();
2184
2185 Ok(($({let $name = (); from_redis_value_ref(
2186 &flatten_items.next().unwrap())?},)*))
2187 }
2188
2189 _ => crate::errors::invalid_type_error!(v, "Not a Array response")
2190 }
2191 }
2192
2193 #[allow(non_snake_case, unused_variables)]
2196 fn from_redis_value(v: Value) -> Result<($($name,)*), ParsingError> {
2197 let v = get_owned_inner_value(v);
2198 let mut n = 0;
2200 $(let $name = (); n += 1;)*
2201 match v {
2202 Value::Array(mut items) => {
2203 if items.len() != n {
2204 crate::errors::invalid_type_error!(Value::Array(items), "Array response of wrong dimension")
2205 }
2206
2207 let mut i = 0;
2209 Ok(($({let $name = (); from_redis_value(
2210 ::std::mem::replace(&mut items[{ i += 1; i - 1 }], Value::Nil)
2211 )?},)*))
2212 }
2213
2214 Value::Set(mut items) => {
2215 if items.len() != n {
2216 crate::errors::invalid_type_error!(Value::Array(items), "Set response of wrong dimension")
2217 }
2218
2219 let mut i = 0;
2221 Ok(($({let $name = (); from_redis_value(
2222 ::std::mem::replace(&mut items[{ i += 1; i - 1 }], Value::Nil)
2223 )?},)*))
2224 }
2225
2226 Value::Map(items) => {
2227 if n != items.len() * 2 {
2228 crate::errors::invalid_type_error!(Value::Map(items), "Map response of wrong dimension")
2229 }
2230
2231 let mut flatten_items = items.into_iter().map(|(a,b)|[a,b]).flatten();
2232
2233 Ok(($({let $name = (); from_redis_value(
2234 ::std::mem::replace(&mut flatten_items.next().unwrap(), Value::Nil)
2235 )?},)*))
2236 }
2237
2238 _ => crate::errors::invalid_type_error!(v, "Not a Array response")
2239 }
2240 }
2241
2242 #[allow(non_snake_case, unused_variables)]
2243 fn from_redis_value_refs(items: &[Value]) -> Result<Vec<($($name,)*)>, ParsingError> {
2244 let mut n = 0;
2246 $(let $name = (); n += 1;)*
2247 if items.len() == 0 {
2248 return Ok(vec![]);
2249 }
2250
2251 if items.iter().all(|item| item.is_collection_of_len(n)) {
2252 return items.iter().map(|item| from_redis_value_ref(item)).collect();
2253 }
2254
2255 let mut rv = Vec::with_capacity(items.len() / n);
2256 if let [$($name),*] = items {
2257 rv.push(($(from_redis_value_ref($name)?,)*));
2258 return Ok(rv);
2259 }
2260 for chunk in items.chunks(n) {
2261 match chunk {
2262 [$($name),*] => rv.push(($(from_redis_value_ref($name)?,)*)),
2263 _ => return Err(format!("Vector of length {} doesn't have arity of {n}", items.len()).into()),
2264 }
2265 }
2266 Ok(rv)
2267 }
2268
2269 #[allow(non_snake_case, unused_variables)]
2270 fn from_each_redis_values(mut items: Vec<Value>) -> Vec<Result<($($name,)*), ParsingError>> {
2271 #[allow(unused_parens)]
2272 let extract = |val: ($(Result<$name, ParsingError>,)*)| -> Result<($($name,)*), ParsingError> {
2273 let ($($name,)*) = val;
2274 Ok(($($name?,)*))
2275 };
2276
2277 let mut n = 0;
2279 $(let $name = (); n += 1;)*
2280
2281 if items.len() == 0 {
2283 return vec![];
2284 }
2285 if items.iter().all(|item| item.is_collection_of_len(n)) {
2286 return items.into_iter().map(|item| from_redis_value(item).map_err(|err|err.into())).collect();
2287 }
2288
2289 let mut rv = Vec::with_capacity(items.len() / n);
2290
2291 for chunk in items.chunks_mut(n) {
2292 match chunk {
2293 [$($name),*] => rv.push(extract(($(from_redis_value(std::mem::replace($name, Value::Nil)).into(),)*))),
2298 _ => return vec![Err(format!("Vector of length {} doesn't have arity of {n}", items.len()).into())],
2299 }
2300 }
2301 rv
2302 }
2303
2304 #[allow(non_snake_case, unused_variables)]
2305 fn from_redis_values(mut items: Vec<Value>) -> Result<Vec<($($name,)*)>, ParsingError> {
2306 let mut n = 0;
2308 $(let $name = (); n += 1;)*
2309
2310 if items.len() == 0 {
2312 return Ok(vec![])
2313 }
2314 if items.iter().all(|item| item.is_collection_of_len(n)) {
2315 return items.into_iter().map(|item| from_redis_value(item)).collect();
2316 }
2317
2318 let mut rv = Vec::with_capacity(items.len() / n);
2319 for chunk in items.chunks_mut(n) {
2320 match chunk {
2321 [$($name),*] => rv.push(($(from_redis_value(std::mem::replace($name, Value::Nil))?,)*)),
2326 _ => return Err(format!("Vector of length {} doesn't have arity of {n}", items.len()).into()),
2327 }
2328 }
2329 Ok(rv)
2330 }
2331 }
2332 )
2333}
2334
2335from_redis_value_for_tuple! { #[cfg_attr(docsrs, doc(fake_variadic))], #[doc = "This trait is implemented for tuples up to 12 items long."], T, }
2336from_redis_value_for_tuple! { #[doc(hidden)], T1, T2, }
2337from_redis_value_for_tuple! { #[doc(hidden)], T1, T2, T3, }
2338from_redis_value_for_tuple! { #[doc(hidden)], T1, T2, T3, T4, }
2339from_redis_value_for_tuple! { #[doc(hidden)], T1, T2, T3, T4, T5, }
2340from_redis_value_for_tuple! { #[doc(hidden)], T1, T2, T3, T4, T5, T6, }
2341from_redis_value_for_tuple! { #[doc(hidden)], T1, T2, T3, T4, T5, T6, T7, }
2342from_redis_value_for_tuple! { #[doc(hidden)], T1, T2, T3, T4, T5, T6, T7, T8, }
2343from_redis_value_for_tuple! { #[doc(hidden)], T1, T2, T3, T4, T5, T6, T7, T8, T9, }
2344from_redis_value_for_tuple! { #[doc(hidden)], T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, }
2345from_redis_value_for_tuple! { #[doc(hidden)], T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, }
2346from_redis_value_for_tuple! { #[doc(hidden)], T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, }
2347
2348impl FromRedisValue for InfoDict {
2349 fn from_redis_value_ref(v: &Value) -> Result<InfoDict, ParsingError> {
2350 let v = get_inner_value(v);
2351 let s: String = from_redis_value_ref(v)?;
2352 Ok(InfoDict::new(&s))
2353 }
2354 fn from_redis_value(v: Value) -> Result<InfoDict, ParsingError> {
2355 let v = get_owned_inner_value(v);
2356 let s: String = from_redis_value(v)?;
2357 Ok(InfoDict::new(&s))
2358 }
2359}
2360
2361impl<T: FromRedisValue> FromRedisValue for Option<T> {
2362 fn from_redis_value_ref(v: &Value) -> Result<Option<T>, ParsingError> {
2363 let v = get_inner_value(v);
2364 if *v == Value::Nil {
2365 return Ok(None);
2366 }
2367 Ok(Some(from_redis_value_ref(v)?))
2368 }
2369 fn from_redis_value(v: Value) -> Result<Option<T>, ParsingError> {
2370 let v = get_owned_inner_value(v);
2371 if v == Value::Nil {
2372 return Ok(None);
2373 }
2374 Ok(Some(from_redis_value(v)?))
2375 }
2376}
2377
2378#[cfg(feature = "bytes")]
2379impl FromRedisValue for bytes::Bytes {
2380 fn from_redis_value_ref(v: &Value) -> Result<Self, ParsingError> {
2381 let v = get_inner_value(v);
2382 match v {
2383 Value::BulkString(bytes_vec) => Ok(bytes::Bytes::copy_from_slice(bytes_vec.as_ref())),
2384 _ => crate::errors::invalid_type_error!(v, "Not a bulk string"),
2385 }
2386 }
2387 fn from_redis_value(v: Value) -> Result<Self, ParsingError> {
2388 let v = get_owned_inner_value(v);
2389 match v {
2390 Value::BulkString(bytes_vec) => Ok(bytes_vec.into()),
2391 _ => crate::errors::invalid_type_error!(v, "Not a bulk string"),
2392 }
2393 }
2394}
2395
2396#[cfg(feature = "uuid")]
2397impl FromRedisValue for uuid::Uuid {
2398 fn from_redis_value_ref(v: &Value) -> Result<Self, ParsingError> {
2399 match *v {
2400 Value::BulkString(ref bytes) => Ok(uuid::Uuid::from_slice(bytes)?),
2401 _ => crate::errors::invalid_type_error!(v, "Response type not uuid compatible."),
2402 }
2403 }
2404
2405 fn from_redis_value(v: Value) -> Result<Self, ParsingError> {
2406 Self::from_redis_value_ref(&v)
2407 }
2408}
2409
2410#[cfg(feature = "uuid")]
2411impl ToRedisArgs for uuid::Uuid {
2412 fn write_redis_args<W>(&self, out: &mut W)
2413 where
2414 W: ?Sized + RedisWrite,
2415 {
2416 out.write_arg(self.as_bytes());
2417 }
2418}
2419
2420#[cfg(feature = "uuid")]
2421impl ToSingleRedisArg for uuid::Uuid {}
2422
2423pub fn from_redis_value_ref<T: FromRedisValue>(v: &Value) -> Result<T, ParsingError> {
2426 FromRedisValue::from_redis_value_ref(v)
2427}
2428
2429pub fn from_redis_value<T: FromRedisValue>(v: Value) -> Result<T, ParsingError> {
2432 FromRedisValue::from_redis_value(v)
2433}
2434
2435pub fn calculate_value_digest<T: ToRedisArgs>(value: T) -> String {
2451 use xxhash_rust::xxh3::xxh3_64;
2452
2453 let args = value.to_redis_args();
2455
2456 let mut combined_bytes = Vec::new();
2459 for arg in args {
2460 combined_bytes.extend_from_slice(&arg);
2461 }
2462
2463 let hash = xxh3_64(&combined_bytes);
2465 format!("{:016x}", hash)
2466}
2467
2468pub fn is_valid_16_bytes_hex_digest(s: &str) -> bool {
2470 s.len() == 16 && s.chars().all(|c| c.is_ascii_hexdigit())
2471}
2472
2473#[derive(Clone, Eq, PartialEq, Default, Debug, Copy)]
2478#[non_exhaustive]
2479pub enum ProtocolVersion {
2480 #[default]
2482 RESP2,
2483 RESP3,
2485}
2486
2487impl ProtocolVersion {
2488 pub fn supports_resp3(&self) -> bool {
2490 !matches!(self, ProtocolVersion::RESP2)
2491 }
2492}
2493
2494#[derive(Clone, Copy)]
2496#[non_exhaustive]
2497pub enum ExpireOption {
2498 NONE,
2500 NX,
2502 XX,
2504 GT,
2506 LT,
2508}
2509
2510impl ToRedisArgs for ExpireOption {
2511 fn write_redis_args<W>(&self, out: &mut W)
2512 where
2513 W: ?Sized + RedisWrite,
2514 {
2515 match self {
2516 ExpireOption::NX => out.write_arg(b"NX"),
2517 ExpireOption::XX => out.write_arg(b"XX"),
2518 ExpireOption::GT => out.write_arg(b"GT"),
2519 ExpireOption::LT => out.write_arg(b"LT"),
2520 _ => {}
2521 }
2522 }
2523}
2524
2525#[derive(Debug, Clone, PartialEq)]
2526pub struct PushInfo {
2528 pub kind: PushKind,
2530 pub data: Vec<Value>,
2532}
2533
2534impl PushInfo {
2535 pub(crate) fn disconnect() -> Self {
2536 PushInfo {
2537 kind: crate::PushKind::Disconnection,
2538 data: vec![],
2539 }
2540 }
2541}
2542
2543pub(crate) type SyncPushSender = std::sync::mpsc::Sender<PushInfo>;
2544
2545#[derive(Debug, Clone, PartialEq)]
2547#[non_exhaustive]
2548pub enum ValueType {
2549 String,
2551 List,
2553 Set,
2555 ZSet,
2557 Hash,
2559 Stream,
2561 Unknown(String),
2563}
2564
2565impl<T: AsRef<str>> From<T> for ValueType {
2566 fn from(s: T) -> Self {
2567 match s.as_ref() {
2568 "string" => ValueType::String,
2569 "list" => ValueType::List,
2570 "set" => ValueType::Set,
2571 "zset" => ValueType::ZSet,
2572 "hash" => ValueType::Hash,
2573 "stream" => ValueType::Stream,
2574 s => ValueType::Unknown(s.to_string()),
2575 }
2576 }
2577}
2578
2579impl From<ValueType> for String {
2580 fn from(v: ValueType) -> Self {
2581 match v {
2582 ValueType::String => "string".to_string(),
2583 ValueType::List => "list".to_string(),
2584 ValueType::Set => "set".to_string(),
2585 ValueType::ZSet => "zset".to_string(),
2586 ValueType::Hash => "hash".to_string(),
2587 ValueType::Stream => "stream".to_string(),
2588 ValueType::Unknown(s) => s,
2589 }
2590 }
2591}
2592
2593impl FromRedisValue for ValueType {
2594 fn from_redis_value_ref(v: &Value) -> Result<Self, ParsingError> {
2595 match v {
2596 Value::SimpleString(s) => Ok(s.into()),
2597 _ => crate::errors::invalid_type_error!(v, "Value type should be a simple string"),
2598 }
2599 }
2600
2601 fn from_redis_value(v: Value) -> Result<Self, ParsingError> {
2602 match v {
2603 Value::SimpleString(s) => Ok(s.into()),
2604 _ => crate::errors::invalid_type_error!(v, "Value type should be a simple string"),
2605 }
2606 }
2607}
2608
2609#[derive(Debug, PartialEq, Clone)]
2611#[non_exhaustive]
2612pub enum IntegerReplyOrNoOp {
2613 IntegerReply(usize),
2615 NotExists,
2617 ExistsButNotRelevant,
2619}
2620
2621impl IntegerReplyOrNoOp {
2622 pub fn raw(&self) -> isize {
2624 match self {
2625 IntegerReplyOrNoOp::IntegerReply(s) => *s as isize,
2626 IntegerReplyOrNoOp::NotExists => -2,
2627 IntegerReplyOrNoOp::ExistsButNotRelevant => -1,
2628 }
2629 }
2630}
2631
2632impl FromRedisValue for IntegerReplyOrNoOp {
2633 fn from_redis_value_ref(v: &Value) -> Result<Self, ParsingError> {
2634 match v {
2635 Value::Int(s) => match s {
2636 -2 => Ok(IntegerReplyOrNoOp::NotExists),
2637 -1 => Ok(IntegerReplyOrNoOp::ExistsButNotRelevant),
2638 _ => Ok(IntegerReplyOrNoOp::IntegerReply(*s as usize)),
2639 },
2640 _ => crate::errors::invalid_type_error!(v, "Value should be an integer"),
2641 }
2642 }
2643
2644 fn from_redis_value(v: Value) -> Result<Self, ParsingError> {
2645 match v {
2646 Value::Int(s) => match s {
2647 -2 => Ok(IntegerReplyOrNoOp::NotExists),
2648 -1 => Ok(IntegerReplyOrNoOp::ExistsButNotRelevant),
2649 _ => Ok(IntegerReplyOrNoOp::IntegerReply(s as usize)),
2650 },
2651 _ => crate::errors::invalid_type_error!(v, "Value should be an integer"),
2652 }
2653 }
2654}
2655
2656impl PartialEq<isize> for IntegerReplyOrNoOp {
2657 fn eq(&self, other: &isize) -> bool {
2658 match self {
2659 IntegerReplyOrNoOp::IntegerReply(s) => *s as isize == *other,
2660 IntegerReplyOrNoOp::NotExists => *other == -2,
2661 IntegerReplyOrNoOp::ExistsButNotRelevant => *other == -1,
2662 }
2663 }
2664}
2665
2666impl PartialEq<usize> for IntegerReplyOrNoOp {
2667 fn eq(&self, other: &usize) -> bool {
2668 match self {
2669 IntegerReplyOrNoOp::IntegerReply(s) => *s == *other,
2670 _ => false,
2671 }
2672 }
2673}
2674
2675impl PartialEq<i32> for IntegerReplyOrNoOp {
2676 fn eq(&self, other: &i32) -> bool {
2677 match self {
2678 IntegerReplyOrNoOp::IntegerReply(s) => *s as i32 == *other,
2679 IntegerReplyOrNoOp::NotExists => *other == -2,
2680 IntegerReplyOrNoOp::ExistsButNotRelevant => *other == -1,
2681 }
2682 }
2683}
2684
2685impl PartialEq<u32> for IntegerReplyOrNoOp {
2686 fn eq(&self, other: &u32) -> bool {
2687 match self {
2688 IntegerReplyOrNoOp::IntegerReply(s) => *s as u32 == *other,
2689 _ => false,
2690 }
2691 }
2692}