redis_driver/resp/
value.rs

1use crate::{
2    resp::{Command, FromValue},
3    Error, RedisError, Result,
4};
5use std::fmt;
6
7#[derive(PartialEq)]
8pub enum Value {
9    SimpleString(String),
10    Integer(i64),
11    Double(f64),
12    BulkString(Option<Vec<u8>>),
13    Array(Option<Vec<Value>>),
14    Push(Option<Vec<Value>>),
15    Error(RedisError),
16}
17
18pub struct BulkString(pub Vec<u8>);
19
20impl Value {
21    /// A [`Value`](crate::resp::Value) to user type conversion that consumes the input value.
22    ///
23    /// # Errors
24    /// Any parsing error ([`Error::Client`](crate::Error::Client)) due to incompatibility between Value variant and taget type
25    pub fn into<T>(self) -> Result<T>
26    where
27        T: FromValue,
28    {
29        T::from_value(self)
30    }
31
32    pub fn into_with_command<T>(self, command: &Command) -> Result<T>
33    where
34        T: FromValue,
35    {
36        T::from_value_with_command(self, command)
37    }
38}
39
40impl Default for Value {
41    fn default() -> Self {
42        Value::BulkString(None)
43    }
44}
45
46impl ToString for Value {
47    fn to_string(&self) -> String {
48        match &self {
49            Value::SimpleString(s) => s.clone(),
50            Value::Integer(i) => i.to_string(),
51            Value::Double(f) => f.to_string(),
52            Value::BulkString(s) => match s {
53                Some(s) => String::from_utf8_lossy(s).into_owned(),
54                None => String::from(""),
55            },
56            Value::Array(Some(v)) => format!(
57                "[{}]",
58                v.iter()
59                    .map(ToString::to_string)
60                    .collect::<Vec<_>>()
61                    .join(", ")
62            ),
63            Value::Array(None) => "[]".to_string(),
64            Value::Push(Some(v)) => format!(
65                "Push[{}]",
66                v.iter()
67                    .map(ToString::to_string)
68                    .collect::<Vec<_>>()
69                    .join(", ")
70            ),
71            Value::Push(None) => "Push[]".to_string(),
72            Value::Error(e) => e.to_string(),
73        }
74    }
75}
76
77impl fmt::Debug for Value {
78    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
79        match self {
80            Self::SimpleString(arg0) => f.debug_tuple("SimpleString").field(arg0).finish(),
81            Self::Integer(arg0) => f.debug_tuple("Integer").field(arg0).finish(),
82            Self::Double(arg0) => f.debug_tuple("Double").field(arg0).finish(),
83            Self::BulkString(Some(arg0)) => f.debug_tuple("CommandArg").field(&String::from_utf8_lossy(arg0).into_owned()).finish(),
84            Self::BulkString(None) => f.debug_tuple("CommandArg").field(&None::<Vec<u8>>).finish(),
85            Self::Array(arg0) => f.debug_tuple("Array").field(arg0).finish(),
86            Self::Push(arg0) => f.debug_tuple("Push").field(arg0).finish(),
87            Self::Error(arg0) => f.debug_tuple("Error").field(arg0).finish(),
88        }
89    }
90}
91
92pub(crate) trait ResultValueExt {
93    fn into_result(self) -> Result<Value>;
94    fn map_into_result<T, F>(self, op: F) -> Result<T>
95    where
96        F: FnOnce(Value) -> T;
97}
98
99impl ResultValueExt for Result<Value> {
100    #[inline]
101    fn into_result(self) -> Result<Value> {
102        match self {
103            Ok(value) => match value {
104                Value::Error(e) => Err(Error::Redis(e)),
105                _ => Ok(value),
106            },
107            Err(e) => Err(e),
108        }
109    }
110
111    #[inline]
112    fn map_into_result<T, F>(self, op: F) -> Result<T>
113    where
114        F: FnOnce(Value) -> T,
115    {
116        match self {
117            Ok(value) => match value {
118                Value::Error(e) => Err(Error::Redis(e)),
119                _ => Ok(op(value)),
120            },
121            Err(e) => Err(e),
122        }
123    }
124}
125
126pub(crate) trait IntoValueIterator: Sized {
127    fn into_value_iter<T>(self) -> ValueIterator<T>
128    where
129        T: FromValue;
130}
131
132impl IntoValueIterator for Vec<Value> {
133    fn into_value_iter<T>(self) -> ValueIterator<T>
134    where
135        T: FromValue,
136    {
137        ValueIterator::new(self.into_iter())
138    }
139}
140
141pub(crate) struct ValueIterator<T>
142where
143    T: FromValue,
144{
145    iter: std::vec::IntoIter<Value>,
146    phantom: std::marker::PhantomData<T>,
147    #[allow(clippy::complexity)]
148    next_functor: Box<dyn FnMut(&mut std::vec::IntoIter<Value>) -> Option<Result<T>>>,
149}
150
151impl<T> ValueIterator<T>
152where
153    T: FromValue,
154{
155    pub fn new(iter: std::vec::IntoIter<Value>) -> Self {
156        Self {
157            iter,
158            phantom: std::marker::PhantomData,
159            next_functor: T::next_functor(),
160        }
161    }
162}
163
164impl<T> Iterator for ValueIterator<T>
165where
166    T: FromValue,
167{
168    type Item = Result<T>;
169
170    fn next(&mut self) -> Option<Self::Item> {
171        (self.next_functor)(&mut self.iter)
172    }
173}