redust_resp/
de.rs

1use std::{borrow::Cow, fmt::Display};
2
3use serde::{de, Deserialize};
4
5mod accessor;
6mod deserializer;
7
8pub(crate) use accessor::*;
9pub use deserializer::*;
10
11use crate::Error;
12
13/// An error occurred while reading bytes.
14#[derive(Debug)]
15pub struct ReadError<'a> {
16	/// The error which occurred.
17	pub data: Error<'a>,
18	/// Bytes remaining to be read.
19	pub remaining: Cow<'a, [u8]>,
20}
21
22impl ReadError<'_> {
23	/// Convert this error into an owned error.
24	pub fn into_owned(self) -> ReadError<'static> {
25		ReadError {
26			data: self.data.into_owned(),
27			remaining: self.remaining.into_owned().into(),
28		}
29	}
30}
31
32impl Display for ReadError<'_> {
33	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34		write!(f, "{}", self.data)
35	}
36}
37
38impl std::error::Error for ReadError<'_> {
39	fn cause(&self) -> Option<&dyn de::StdError> {
40		Some(&self.data)
41	}
42}
43
44/// Deserialize RESP bytes, returning the target and any remaining bytes.
45pub fn from_bytes<'de, T: Deserialize<'de>>(
46	data: &'de [u8],
47) -> Result<(T, &'de [u8]), ReadError<'de>> {
48	let mut de = Deserializer { input: data };
49	let res = T::deserialize(&mut de).map_err(|e| ReadError {
50		data: e,
51		remaining: de.input.into(),
52	})?;
53	Ok((res, de.input))
54}
55
56#[cfg(test)]
57mod test {
58	use std::collections::HashMap;
59
60	use serde_bytes::Bytes;
61
62	use crate::{array, from_bytes, Data, Error};
63
64	#[test]
65	fn de_int() {
66		let data = b":1\r\n";
67		let (res, rem) = from_bytes::<u8>(data).unwrap();
68
69		assert_eq!(res, 1);
70		assert_eq!(rem, []);
71	}
72
73	#[test]
74	fn de_str() {
75		let data = b"+foo\r\n";
76		let (res, rem) = from_bytes::<&str>(data).unwrap();
77
78		assert_eq!(res, "foo");
79		assert_eq!(rem, []);
80	}
81
82	#[test]
83	fn de_error() {
84		let data = b"-foo\r\n";
85		let err = from_bytes::<()>(data).unwrap_err();
86
87		match err.data {
88			Error::Redis(_) => {}
89			_ => panic!("unexpected error type {}", err),
90		}
91	}
92
93	#[test]
94	fn de_bytes() {
95		let data = b"$3\r\nfoo\r\n";
96		let (res, rem) = from_bytes::<&[u8]>(data).unwrap();
97
98		assert_eq!(res, b"foo");
99		assert_eq!(rem, []);
100	}
101
102	#[test]
103	fn de_null_bytes() {
104		let data = b"$-1\r\n";
105		let (res, rem) = from_bytes::<Option<&[u8]>>(data).unwrap();
106
107		assert_eq!(res, None);
108		assert_eq!(rem, []);
109	}
110
111	#[test]
112	fn de_arr() {
113		let data = b"*1\r\n+foo\r\n";
114		let (res, rem) = from_bytes::<Vec<String>>(data).unwrap();
115
116		assert_eq!(res, ["foo"]);
117		assert_eq!(rem, []);
118	}
119
120	#[test]
121	fn de_null_arr() {
122		let data = b"*-1\r\n";
123		let (res, rem) = from_bytes::<Option<Vec<i64>>>(data).unwrap();
124
125		assert_eq!(res, None);
126		assert_eq!(rem, []);
127	}
128
129	#[test]
130	fn de_nested_arr() {
131		let data = b"*2\r\n+foo\r\n*1\r\n$3\r\nbar\r\n";
132		let (res, rem) = from_bytes::<(&str, Vec<&[u8]>)>(data).unwrap();
133
134		assert_eq!(res, ("foo", [&b"bar"[..]].to_vec()));
135		assert_eq!(rem, []);
136	}
137
138	#[test]
139	fn de_pubsub_subscribe() {
140		let data = b"*3\r\n$9\r\nsubscribe\r\n$3\r\nfoo\r\n:1\r\n";
141		let (res, rem) = from_bytes::<(&Bytes, &Bytes, usize)>(data).unwrap();
142
143		assert_eq!(res, (Bytes::new(b"subscribe"), Bytes::new(b"foo"), 1));
144		assert_eq!(rem, []);
145	}
146
147	#[test]
148	fn de_map() {
149		let data = b"*2\r\n+foo\r\n*1\r\n$3\r\nbar\r\n";
150		let (res, rem) = from_bytes::<HashMap<&str, Vec<&Bytes>>>(data).unwrap();
151
152		let mut exp = HashMap::new();
153		exp.insert("foo", vec![Bytes::new(b"bar")]);
154
155		assert_eq!(res, exp);
156		assert_eq!(rem, []);
157	}
158
159	#[test]
160	fn de_data_str() {
161		let bytes = b"+OK\r\n";
162		let (data, rem) = from_bytes::<Data>(bytes).unwrap();
163
164		assert_eq!(data, Data::SimpleString("OK".into()));
165		assert_eq!(rem, []);
166	}
167
168	#[test]
169	fn de_data_err() {
170		let bytes = b"-Error\r\n";
171		let err = from_bytes::<Data>(bytes).unwrap_err();
172
173		match err.data {
174			Error::Redis(msg) if msg == "Error" => {}
175			_ => panic!(),
176		}
177	}
178
179	#[test]
180	fn de_data_int() {
181		let bytes = b":123\r\n";
182		let (data, rem) = from_bytes::<Data>(bytes).unwrap();
183
184		assert_eq!(data, Data::Integer(123));
185		assert_eq!(rem, []);
186	}
187
188	#[test]
189	fn de_data_bulk_str() {
190		let bytes = b"$3\r\nfoo\r\n";
191		let (data, rem) = from_bytes::<Data>(bytes).unwrap();
192
193		assert_eq!(data, Data::bulk_string("foo"));
194		assert_eq!(rem, []);
195	}
196
197	#[test]
198	fn de_data_arr() {
199		let bytes = b"*2\r\n$5\r\nhello\r\n$5\r\nworld\r\n";
200		let (data, rem) = from_bytes::<Data>(bytes).unwrap();
201
202		assert_eq!(
203			data,
204			array!(Data::bulk_string("hello"), Data::bulk_string("world"))
205		);
206		assert_eq!(rem, []);
207	}
208
209	#[test]
210	fn de_data_null_arr() {
211		let data = b"*-1\r\n";
212		let (res, rem) = from_bytes::<Data>(data).unwrap();
213
214		assert_eq!(res, ());
215		assert_eq!(rem, []);
216	}
217
218	#[test]
219	fn de_data_some_arr() {
220		let data = b"*0\r\n";
221		let (res, rem) = from_bytes::<Option<Data>>(data).unwrap();
222
223		assert_eq!(res, Some(array!()));
224		assert_eq!(rem, []);
225	}
226}