1use std::{
2 io::Cursor,
3 str::{from_utf8, FromStr},
4};
5
6use crate::error::AnyError;
7
8use super::{Deserialize, Deserializer, MapAccess, Peek, SeqAccess, Visitor};
9
10pub trait FromJson: Sized {
11 fn from_json(str: &str) -> Result<Self, AnyError>;
12}
13
14impl<D: Deserialize> FromJson for D {
15 fn from_json(str: &str) -> Result<Self, AnyError> {
16 let mut de = JsonDeserializer {
17 read: Cursor::new(str),
18 };
19 Self::deserialize(&mut de)
20 }
21}
22
23macro_rules! impl_deserializer_primitive {
24 ($ttype: ident, $deserialize_fn: ident, $parse_fn: ident, $visit_fn: ident) => {
25 fn $deserialize_fn<V: Visitor>(self, v: V) -> Result<V::Value, AnyError> {
26 self.parse_whitespaces()?;
27 match self.read.peek()? {
28 Some(b'-') | Some(b'0') | Some(b'1') | Some(b'2') | Some(b'3') | Some(b'4')
29 | Some(b'5') | Some(b'6') | Some(b'7') | Some(b'8') | Some(b'9') | Some(b'.') => {
30 let str = self
31 .read
32 .read_until(&[b' ', b',', b'\t', b'\n', b']', b'}', b':'])?;
33 let str = from_utf8(str.as_slice())?;
34 let val = self.$parse_fn(str)?;
35 v.$visit_fn(val)
36 }
37 Some(b'"') => {
38 self.read.consume()?;
39 let str = self.read.read_until(&[b'"'])?;
40 self.read.consume()?;
41 let str = from_utf8(str.as_slice())?;
42 let val = self.$parse_fn(str)?;
43 v.$visit_fn(val)
44 }
45 Some(_) | None => {
46 Err(concat!("expected a ", stringify!($ttype), " to start").into())
47 }
48 }
49 }
50 };
51 ($ttype: ident as $cast: ident, $deserialize_fn: ident, $parse_fn: ident, $visit_fn: ident) => {
52 fn $deserialize_fn<V: Visitor>(self, v: V) -> Result<V::Value, AnyError> {
53 self.parse_whitespaces()?;
54 match self.read.peek()? {
55 Some(b'-') | Some(b'0') | Some(b'1') | Some(b'2') | Some(b'3') | Some(b'4')
56 | Some(b'5') | Some(b'6') | Some(b'7') | Some(b'8') | Some(b'9') | Some(b'.') => {
57 let str = self
58 .read
59 .read_until(&[b' ', b',', b'\t', b'\n', b']', b'}', b':'])?;
60 let str = from_utf8(str.as_slice())?;
61 let val = self.$parse_fn(str)?;
62 v.$visit_fn(val as $cast)
63 }
64 Some(b'"') => {
65 self.read.consume()?;
66 let str = self.read.read_until(&[b'"'])?;
67 self.read.consume()?;
68 let str = from_utf8(str.as_slice())?;
69 let val = self.$parse_fn(str)?;
70 v.$visit_fn(val)
71 }
72 Some(_) | None => {
73 Err(concat!("expected a ", stringify!($ttype), " to start").into())
74 }
75 }
76 }
77 };
78}
79
80pub struct JsonDeserializer<P: Peek> {
81 read: P,
82}
83
84struct JsonMap<'de, P: Peek> {
85 de: &'de mut JsonDeserializer<P>,
86}
87
88struct JsonArray<'de, P: Peek> {
89 de: &'de mut JsonDeserializer<P>,
90}
91
92impl<P: Peek> JsonDeserializer<P> {
93 pub fn new(peek: P) -> Self {
94 Self { read: peek }
95 }
96
97 fn parse_whitespaces(&mut self) -> Result<(), AnyError> {
98 self.read.consume_matching(&[b' ', b'\n', b'\t'])
99 }
100
101 fn parse_signed_number<I: FromStr>(&mut self, str: &str) -> Result<I, AnyError>
102 where
103 <I as FromStr>::Err: std::error::Error + 'static,
104 {
105 str.parse().map_err(|err| Box::from(err))
106 }
107
108 fn parse_unsigned_number<U: FromStr>(&mut self, str: &str) -> Result<U, AnyError>
109 where
110 <U as FromStr>::Err: std::error::Error + 'static,
111 {
112 str.parse().map_err(|err| Box::from(err))
113 }
114
115 fn parse_floating_number<F: FromStr>(&mut self, str: &str) -> Result<F, AnyError>
116 where
117 <F as FromStr>::Err: std::error::Error + 'static,
118 {
119 str.parse().map_err(|err| Box::from(err))
120 }
121}
122
123impl<P: Peek> Deserializer for &mut JsonDeserializer<P> {
124 fn deserialize_map<V: Visitor>(self, v: V) -> Result<V::Value, AnyError> {
125 self.parse_whitespaces()?;
126 match self.read.peek()? {
127 Some(b'{') => {
128 self.read.consume()?;
129 let val = v.visit_map(JsonMap { de: self });
130 self.read.consume()?;
131 val
132 }
133 Some(char) => {
134 Err(format!("expected a map to start but got \"{}\" instead", char).into())
135 }
136 None => Err("expected a map to start".into()),
137 }
138 }
139
140 fn deserialize_seq<V: Visitor>(self, v: V) -> Result<V::Value, AnyError> {
141 self.parse_whitespaces()?;
142 match self.read.peek()? {
143 Some(b'[') => {
144 self.read.consume()?;
145 v.visit_seq(JsonArray { de: self })
146 }
147 Some(_) | None => Err("expected a vec to start".into()),
148 }
149 }
150
151 fn deserialize_struct<V: Visitor>(self, v: V) -> Result<V::Value, AnyError> {
152 self.deserialize_map(v)
153 }
154
155 fn deserialize_str<V: Visitor>(self, v: V) -> Result<V::Value, AnyError> {
156 self.parse_whitespaces()?;
157 match self.read.peek()? {
158 Some(b'"') => {
159 self.read.consume()?;
160 let str = self.read.read_until(&[b'"'])?;
161 self.read.consume()?;
162 let str = from_utf8(str.as_slice())?;
163 v.visit_str(str)
164 }
165 Some(_) | None => Err("expected a str to start".into()),
166 }
167 }
168
169 impl_deserializer_primitive!(i8, deserialize_i8, parse_signed_number, visit_i8);
170 impl_deserializer_primitive!(i16, deserialize_i16, parse_signed_number, visit_i16);
171 impl_deserializer_primitive!(i32, deserialize_i32, parse_signed_number, visit_i32);
172 impl_deserializer_primitive!(i64, deserialize_i64, parse_signed_number, visit_i64);
173 impl_deserializer_primitive!(i128, deserialize_i128, parse_signed_number, visit_i128);
174 impl_deserializer_primitive!(u8, deserialize_u8, parse_unsigned_number, visit_u8);
175 impl_deserializer_primitive!(u16, deserialize_u16, parse_unsigned_number, visit_u16);
176 impl_deserializer_primitive!(u32, deserialize_u32, parse_unsigned_number, visit_u32);
177 impl_deserializer_primitive!(u64, deserialize_u64, parse_unsigned_number, visit_u64);
178 impl_deserializer_primitive!(u128, deserialize_u128, parse_unsigned_number, visit_u128);
179 impl_deserializer_primitive!(f32, deserialize_f32, parse_floating_number, visit_f32);
180 impl_deserializer_primitive!(f64, deserialize_f64, parse_floating_number, visit_f64);
181 impl_deserializer_primitive!(isize, deserialize_isize, parse_signed_number, visit_isize);
182 impl_deserializer_primitive!(usize, deserialize_usize, parse_unsigned_number, visit_usize);
183}
184
185impl<'de, P: Peek> MapAccess for JsonMap<'de, P> {
186 fn next_value<V: Deserialize>(&mut self) -> Result<V, AnyError> {
187 self.de.parse_whitespaces()?;
188 match self.de.read.peek()? {
189 Some(b':') => {
190 self.de.read.consume()?;
191 self.de.parse_whitespaces()?;
192 match self.de.read.peek()? {
193 Some(b'0') | Some(b'1') | Some(b'2') | Some(b'3') | Some(b'4') | Some(b'5')
194 | Some(b'6') | Some(b'7') | Some(b'8') | Some(b'9') | Some(b'-')
195 | Some(b'"') | Some(b'{') | Some(b'[') => Ok(V::deserialize(&mut *self.de)?),
196 Some(_) | None => Err("expected a map value".into()),
197 }
198 }
199 Some(_) | None => Err("expected a map assignment".into()),
200 }
201 }
202
203 fn next_key<K: Deserialize>(&mut self) -> Result<Option<K>, AnyError> {
204 self.de.parse_whitespaces()?;
205 match self.de.read.peek()? {
206 Some(b'"') => Ok(Some(K::deserialize(&mut *self.de)?)),
207 Some(b',') => {
208 self.de.read.consume()?;
209 self.next_key()
210 }
211 Some(b'}') => Ok(None),
212 Some(_) | None => Err("expected a map key".into()),
213 }
214 }
215}
216
217impl<'de, P: Peek> SeqAccess for JsonArray<'de, P> {
218 fn next_value<V: Deserialize>(&mut self) -> Result<Option<V>, AnyError> {
219 self.de.parse_whitespaces()?;
220 match self.de.read.peek()? {
221 Some(b',') => {
222 self.de.read.consume()?;
223 self.next_value()
224 }
225 Some(b']') => {
226 self.de.read.consume()?;
227 Ok(None)
228 }
229 Some(b'"') | Some(_) => Ok(Some(V::deserialize(&mut *self.de)?)),
230 None => Err("expected a seq element".into()),
231 }
232 }
233}
234
235#[cfg(test)]
236mod test {
237 use std::{collections::HashMap, io::Cursor};
238
239 use super::*;
240
241 #[test]
242 fn parse_vec_test() {
243 let expected = vec![32i32, 64i32];
244
245 let input = "[32, 64]";
246 let input = Cursor::new(input);
247 let mut de = JsonDeserializer { read: input };
248 let result = Vec::<i32>::deserialize(&mut de);
249
250 dbg!(&result);
251 assert!(result.is_ok());
252 assert_eq!(result.unwrap(), expected);
253 }
254
255 #[test]
256 fn parse_map_test() {
257 let mut expected = HashMap::new();
258 expected.insert(2i32, 32i32);
259
260 let input = "{ \"2\": 32 }";
261 let input = Cursor::new(input);
262 let mut de = JsonDeserializer { read: input };
263 let map = HashMap::<i32, i32>::deserialize(&mut de);
264
265 dbg!(&map);
266 assert!(map.is_ok());
267 assert_eq!(map.unwrap(), expected);
268 }
269
270 #[test]
271 fn parse_struct_test() {
272 #[derive(Debug)]
273 struct A {
274 a: i32,
275 s: String,
276 }
277
278 impl Deserialize for A {
279 fn deserialize<D: Deserializer>(des: D) -> Result<Self, AnyError> {
280 enum Field {
281 A,
282 S,
283 }
284
285 impl Deserialize for Field {
286 fn deserialize<D: Deserializer>(des: D) -> Result<Self, AnyError> {
287 struct FieldVisitor {}
288 impl Visitor for FieldVisitor {
289 type Value = Field;
290
291 fn visit_str(self, v: &str) -> Result<Self::Value, AnyError> {
292 match v {
293 "a" => Ok(Field::A),
294 "s" => Ok(Field::S),
295 val => Err(format!("unknown \"{}\" field for A", val).into()),
296 }
297 }
298
299 fn expected_a(self) -> String {
300 "A field".into()
301 }
302 }
303
304 des.deserialize_str(FieldVisitor {})
305 }
306 }
307
308 struct AVisitor {}
309 impl Visitor for AVisitor {
310 type Value = A;
311
312 fn expected_a(self) -> String {
313 "A".into()
314 }
315
316 fn visit_map<M: MapAccess>(self, mut map: M) -> Result<Self::Value, AnyError> {
317 let mut a = None;
318 let mut s = None;
319
320 while let Some(key) = map.next_key()? {
321 match key {
322 Field::A => {
323 if a.is_some() {
324 return Err("duplicate field a".into());
325 };
326 a = Some(map.next_value()?)
327 }
328 Field::S => {
329 if s.is_some() {
330 return Err("duplicate field s".into());
331 };
332 s = Some(map.next_value()?)
333 }
334 }
335 }
336
337 let a = a.ok_or_else(|| "missing field a")?;
338 let s = s.ok_or_else(|| "missing field s")?;
339
340 Ok(A { a: a, s: s })
341 }
342 }
343
344 des.deserialize_struct(AVisitor {})
345 }
346 }
347
348 let input = "{ \"a\": \"32\", \"s\": \"well well well\" }";
349 let input = Cursor::new(input);
350
351 let mut de = JsonDeserializer { read: input };
352
353 let a = A::deserialize(&mut de);
354
355 dbg!(&a);
356 assert!(a.is_ok());
357 assert_eq!(a.as_ref().unwrap().a, 32);
358 assert_eq!(a.as_ref().unwrap().s, "well well well".to_string());
359 }
360}