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#[derive(Debug)]
15pub struct ReadError<'a> {
16 pub data: Error<'a>,
18 pub remaining: Cow<'a, [u8]>,
20}
21
22impl ReadError<'_> {
23 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
44pub 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}