redis_driver/resp/
value.rs1use 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 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}