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 + Hash + Eq)
1428);
1429
1430impl_to_redis_args_for_set!(
1431 for <T> std::collections::BTreeSet<T>,
1432 where (T: ToRedisArgs + Hash + Eq + Ord)
1433);
1434
1435#[cfg(feature = "hashbrown")]
1436impl_to_redis_args_for_set!(
1437 for <T, S> hashbrown::HashSet<T, S>,
1438 where (T: ToRedisArgs + Hash + Eq)
1439);
1440
1441#[cfg(feature = "ahash")]
1442impl_to_redis_args_for_set!(
1443 for <T, S> ahash::AHashSet<T, S>,
1444 where (T: ToRedisArgs + Hash + Eq)
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 + Hash + Eq + Ord, V: ToRedisArgs)
1483);
1484
1485impl_to_redis_args_for_map!(
1486 for <K, V> std::collections::BTreeMap<K, V>,
1488 where (K: ToRedisArgs + Hash + Eq + Ord, 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 + Hash + Eq + Ord, 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 + Hash + Eq + Ord, 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 + Hash + 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 + Eq + 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 String,
2553 List,
2555 Set,
2557 ZSet,
2559 Hash,
2561 Stream,
2563 Unknown(String),
2565}
2566
2567impl<T: AsRef<str>> From<T> for ValueType {
2568 fn from(s: T) -> Self {
2569 match s.as_ref() {
2570 "string" => ValueType::String,
2571 "list" => ValueType::List,
2572 "set" => ValueType::Set,
2573 "zset" => ValueType::ZSet,
2574 "hash" => ValueType::Hash,
2575 "stream" => ValueType::Stream,
2576 s => ValueType::Unknown(s.to_string()),
2577 }
2578 }
2579}
2580
2581impl From<ValueType> for String {
2582 fn from(v: ValueType) -> Self {
2583 match v {
2584 ValueType::String => "string".to_string(),
2585 ValueType::List => "list".to_string(),
2586 ValueType::Set => "set".to_string(),
2587 ValueType::ZSet => "zset".to_string(),
2588 ValueType::Hash => "hash".to_string(),
2589 ValueType::Stream => "stream".to_string(),
2590 ValueType::Unknown(s) => s,
2591 }
2592 }
2593}
2594
2595impl FromRedisValue for ValueType {
2596 fn from_redis_value_ref(v: &Value) -> Result<Self, ParsingError> {
2597 match v {
2598 Value::SimpleString(s) => Ok(s.into()),
2599 _ => crate::errors::invalid_type_error!(v, "Value type should be a simple string"),
2600 }
2601 }
2602
2603 fn from_redis_value(v: Value) -> Result<Self, ParsingError> {
2604 match v {
2605 Value::SimpleString(s) => Ok(s.into()),
2606 _ => crate::errors::invalid_type_error!(v, "Value type should be a simple string"),
2607 }
2608 }
2609}
2610
2611#[derive(Debug, PartialEq, Clone)]
2613#[non_exhaustive]
2614pub enum IntegerReplyOrNoOp {
2615 IntegerReply(usize),
2617 NotExists,
2619 ExistsButNotRelevant,
2621}
2622
2623impl IntegerReplyOrNoOp {
2624 pub fn raw(&self) -> isize {
2626 match self {
2627 IntegerReplyOrNoOp::IntegerReply(s) => *s as isize,
2628 IntegerReplyOrNoOp::NotExists => -2,
2629 IntegerReplyOrNoOp::ExistsButNotRelevant => -1,
2630 }
2631 }
2632}
2633
2634impl FromRedisValue for IntegerReplyOrNoOp {
2635 fn from_redis_value_ref(v: &Value) -> Result<Self, ParsingError> {
2636 match v {
2637 Value::Int(s) => match s {
2638 -2 => Ok(IntegerReplyOrNoOp::NotExists),
2639 -1 => Ok(IntegerReplyOrNoOp::ExistsButNotRelevant),
2640 _ => Ok(IntegerReplyOrNoOp::IntegerReply(*s as usize)),
2641 },
2642 _ => crate::errors::invalid_type_error!(v, "Value should be an integer"),
2643 }
2644 }
2645
2646 fn from_redis_value(v: Value) -> Result<Self, ParsingError> {
2647 match v {
2648 Value::Int(s) => match s {
2649 -2 => Ok(IntegerReplyOrNoOp::NotExists),
2650 -1 => Ok(IntegerReplyOrNoOp::ExistsButNotRelevant),
2651 _ => Ok(IntegerReplyOrNoOp::IntegerReply(s as usize)),
2652 },
2653 _ => crate::errors::invalid_type_error!(v, "Value should be an integer"),
2654 }
2655 }
2656}
2657
2658impl PartialEq<isize> for IntegerReplyOrNoOp {
2659 fn eq(&self, other: &isize) -> bool {
2660 match self {
2661 IntegerReplyOrNoOp::IntegerReply(s) => *s as isize == *other,
2662 IntegerReplyOrNoOp::NotExists => *other == -2,
2663 IntegerReplyOrNoOp::ExistsButNotRelevant => *other == -1,
2664 }
2665 }
2666}
2667
2668impl PartialEq<usize> for IntegerReplyOrNoOp {
2669 fn eq(&self, other: &usize) -> bool {
2670 match self {
2671 IntegerReplyOrNoOp::IntegerReply(s) => *s == *other,
2672 _ => false,
2673 }
2674 }
2675}
2676
2677impl PartialEq<i32> for IntegerReplyOrNoOp {
2678 fn eq(&self, other: &i32) -> bool {
2679 match self {
2680 IntegerReplyOrNoOp::IntegerReply(s) => *s as i32 == *other,
2681 IntegerReplyOrNoOp::NotExists => *other == -2,
2682 IntegerReplyOrNoOp::ExistsButNotRelevant => *other == -1,
2683 }
2684 }
2685}
2686
2687impl PartialEq<u32> for IntegerReplyOrNoOp {
2688 fn eq(&self, other: &u32) -> bool {
2689 match self {
2690 IntegerReplyOrNoOp::IntegerReply(s) => *s as u32 == *other,
2691 _ => false,
2692 }
2693 }
2694}