redust_resp/data/
de.rs

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
14/// Deserialize [Data] into `T`.
15pub 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}