1use std::borrow::Cow;
2
3use itertools::Itertools;
4use serde::{
5 de::{
6 self,
7 value::{MapDeserializer, SeqDeserializer},
8 },
9 forward_to_deserialize_any, Deserialize,
10};
11
12use crate::{Data, Error};
13
14pub fn from_data<'de, T>(data: Data<'de>) -> Result<T, Error<'de>>
16where
17 T: Deserialize<'de>,
18{
19 T::deserialize(data)
20}
21
22impl<'de> de::Deserialize<'de> for Data<'de> {
23 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
24 where
25 D: serde::Deserializer<'de>,
26 {
27 struct Visitor;
28
29 impl<'de> de::Visitor<'de> for Visitor {
30 type Value = Data<'de>;
31
32 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
33 write!(formatter, "valid RESP data")
34 }
35
36 fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
37 where
38 E: de::Error,
39 {
40 Ok(Data::Integer(v))
41 }
42
43 fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
44 where
45 E: de::Error,
46 {
47 Ok(Data::SimpleString(Cow::Owned(v)))
48 }
49
50 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
51 where
52 E: de::Error,
53 {
54 self.visit_string(v.to_owned())
55 }
56
57 fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
58 where
59 E: de::Error,
60 {
61 Ok(Data::SimpleString(Cow::Borrowed(v)))
62 }
63
64 fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
65 where
66 E: de::Error,
67 {
68 Ok(Data::BulkString(Cow::Owned(v)))
69 }
70
71 fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
72 where
73 E: de::Error,
74 {
75 self.visit_byte_buf(v.to_owned())
76 }
77
78 fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>
79 where
80 E: de::Error,
81 {
82 Ok(Data::BulkString(Cow::Borrowed(v)))
83 }
84
85 fn visit_none<E>(self) -> Result<Self::Value, E>
86 where
87 E: de::Error,
88 {
89 Ok(Data::Null)
90 }
91
92 fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
93 where
94 D: serde::Deserializer<'de>,
95 {
96 de::Deserialize::deserialize(deserializer)
97 }
98
99 fn visit_unit<E>(self) -> Result<Self::Value, E>
100 where
101 E: de::Error,
102 {
103 self.visit_none()
104 }
105
106 fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
107 where
108 D: serde::Deserializer<'de>,
109 {
110 de::Deserialize::deserialize(deserializer)
111 }
112
113 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
114 where
115 A: de::SeqAccess<'de>,
116 {
117 let mut out = Vec::with_capacity(seq.size_hint().unwrap_or(0));
118 while let Some(v) = seq.next_element()? {
119 out.push(v);
120 }
121
122 Ok(Data::Array(out))
123 }
124 }
125
126 deserializer.deserialize_any(Visitor)
127 }
128}
129
130fn visit_array<'de, V>(
131 array: impl Iterator<Item = Data<'de>>,
132 visitor: V,
133) -> Result<V::Value, Error<'de>>
134where
135 V: de::Visitor<'de>,
136{
137 let mut deserializer = SeqDeserializer::new(array);
138 let seq = visitor.visit_seq(&mut deserializer)?;
139 deserializer.end()?;
140 Ok(seq)
141}
142
143fn visit_map<'de, V>(
144 array: impl Iterator<Item = Data<'de>>,
145 visitor: V,
146) -> Result<V::Value, Error<'de>>
147where
148 V: de::Visitor<'de>,
149{
150 let mut deserializer = MapDeserializer::new(array.tuples::<(_, _)>());
151 let seq = visitor.visit_map(&mut deserializer)?;
152 deserializer.end()?;
153 Ok(seq)
154}
155
156impl<'de> de::Deserializer<'de> for Data<'de> {
157 type Error = Error<'de>;
158
159 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
160 where
161 V: de::Visitor<'de>,
162 {
163 match self {
164 Data::Array(data) => visit_array(data.into_iter(), visitor),
165 Data::BulkString(bytes) => match bytes {
166 Cow::Owned(b) => visitor.visit_byte_buf(b),
167 Cow::Borrowed(b) => visitor.visit_borrowed_bytes(b),
168 },
169 Data::Integer(i) => visitor.visit_i64(i),
170 Data::Null => visitor.visit_none(),
171 Data::SimpleString(str) => match str {
172 Cow::Owned(s) => visitor.visit_string(s),
173 Cow::Borrowed(s) => visitor.visit_borrowed_str(s),
174 },
175 }
176 }
177
178 fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
179 where
180 V: de::Visitor<'de>,
181 {
182 fn make_err<T, E>(unex: de::Unexpected) -> Result<T, E>
183 where
184 E: de::Error,
185 {
186 Err(de::Error::invalid_type(unex, &"sequence"))
187 }
188
189 match self {
190 Data::Array(data) => visit_map(data.into_iter(), visitor),
191 Data::BulkString(b) => make_err(de::Unexpected::Bytes(&b)),
192 Data::Integer(i) => make_err(de::Unexpected::Signed(i)),
193 Data::Null => make_err(de::Unexpected::Unit),
194 Data::SimpleString(str) => make_err(de::Unexpected::Str(&str)),
195 }
196 }
197
198 fn deserialize_struct<V>(
199 self,
200 _name: &'static str,
201 _fields: &'static [&'static str],
202 visitor: V,
203 ) -> Result<V::Value, Self::Error>
204 where
205 V: de::Visitor<'de>,
206 {
207 self.deserialize_map(visitor)
208 }
209
210 fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
211 where
212 V: de::Visitor<'de>,
213 {
214 match self {
215 Self::Null => visitor.visit_none(),
216 _ => visitor.visit_some(self),
217 }
218 }
219
220 forward_to_deserialize_any! {
221 bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
222 bytes byte_buf unit unit_struct newtype_struct seq tuple
223 tuple_struct enum identifier ignored_any
224 }
225}
226
227impl<'de> de::IntoDeserializer<'de, Error<'de>> for Data<'de> {
228 type Deserializer = Self;
229
230 fn into_deserializer(self) -> Self::Deserializer {
231 self
232 }
233}
234
235#[cfg(test)]
236mod test {
237 use crate::{array, Data};
238
239 use super::from_data;
240
241 #[test]
242 fn to_str() {
243 let res = from_data::<&str>(Data::simple_string("foo")).unwrap();
244 assert_eq!(res, "foo");
245 }
246
247 #[test]
248 fn to_bytes() {
249 let res = from_data::<&[u8]>(Data::bulk_string(b"foo")).unwrap();
250 assert_eq!(res, b"foo");
251 }
252
253 #[test]
254 fn to_arr() {
255 let res = from_data::<Vec<&str>>(array!(Data::simple_string("foo"))).unwrap();
256 assert_eq!(res, vec!["foo"]);
257 }
258
259 #[test]
260 fn to_int() {
261 let res = from_data::<isize>(Data::Integer(42)).unwrap();
262 assert_eq!(res, 42);
263 }
264}