1use std::borrow::Cow;
2use std::fmt::Display;
3
4use serde::de::value::{MapAccessDeserializer, MapDeserializer, SeqDeserializer, StrDeserializer};
5use serde::de::{IntoDeserializer, Visitor};
6use serde::Deserializer;
7
8use crate::parser::{Type, Value};
9
10#[derive(Debug, Clone, Copy)]
11pub enum MaterializedType {
12 Unit,
13 Bool,
14 I8,
15 I16,
16 I32,
17 I64,
18 U8,
19 U16,
20 U32,
21 U64,
22 F32,
23 F64,
24 Char,
25 String,
26 Bytes,
27 List,
28 Map,
29 Enum,
30}
31
32impl Display for MaterializedType {
33 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34 let name = match self {
35 MaterializedType::Unit => "null",
36 MaterializedType::Bool => "a boolean",
37 MaterializedType::I8 => "an 8-bit signed integer",
38 MaterializedType::I16 => "a 16-bit signed integer",
39 MaterializedType::I32 => "a 32-bit signed integer",
40 MaterializedType::I64 => "a 64-bit signed integer",
41 MaterializedType::U8 => "an 8-bit positive integer",
42 MaterializedType::U16 => "a 16-bit positive integer",
43 MaterializedType::U32 => "a 32-bit positive integer",
44 MaterializedType::U64 => "a 64-bit positive integer",
45 MaterializedType::F32 => "a single precision float",
46 MaterializedType::F64 => "a double precision float",
47 MaterializedType::Char => "a single character",
48 MaterializedType::String => "text",
49 MaterializedType::Bytes => "a list of 8-bit unsigned integers",
50 MaterializedType::List => "a list of values",
51 MaterializedType::Map => "a key-value map",
52 MaterializedType::Enum => "an enumeration",
53 };
54
55 write!(f, "{name}")
56 }
57}
58
59#[derive(Debug, thiserror::Error)]
60pub enum DecodeError {
61 #[error("{0}")]
62 Message(String),
63 #[error("Cannot dynamically deserialize value of type {typ}")]
64 DeserializeAnyError { typ: Type },
65 #[error("expected {expected} but got value of type {got}")]
66 TypeError {
67 expected: MaterializedType,
68 got: Type,
69 },
70 #[error("cannot fit the number {got} into {expected}")]
71 RangeError {
72 expected: MaterializedType,
73 got: i64,
74 },
75 #[error("expected list of length {expected} but got list of length {got}")]
76 LengthMismatch { expected: usize, got: usize },
77}
78
79impl serde::de::Error for DecodeError {
80 fn custom<T: Display>(msg: T) -> Self {
81 DecodeError::Message(msg.to_string())
82 }
83}
84
85pub struct RyanDeserializer<'de> {
86 pub(crate) value: Cow<'de, Value>,
87}
88
89impl<'de> IntoDeserializer<'de, DecodeError> for RyanDeserializer<'de> {
90 type Deserializer = Self;
91 fn into_deserializer(self) -> Self::Deserializer {
92 self
93 }
94}
95
96impl<'de> Deserializer<'de> for RyanDeserializer<'de> {
97 type Error = DecodeError;
98
99 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
100 where
101 V: Visitor<'de>,
102 {
103 match &*self.value {
104 Value::Null => self.deserialize_unit(visitor),
105 Value::Bool(_) => self.deserialize_bool(visitor),
106 Value::Integer(_) => self.deserialize_i64(visitor),
107 Value::Float(_) => self.deserialize_f64(visitor),
108 Value::Text(_) => self.deserialize_str(visitor),
109 Value::List(_) => self.deserialize_seq(visitor),
110 Value::Map(_) => self.deserialize_map(visitor),
111 v => Err(DecodeError::DeserializeAnyError {
112 typ: v.canonical_type(),
113 }),
114 }
115 }
116
117 fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
118 where
119 V: Visitor<'de>,
120 {
121 match &*self.value {
122 &Value::Bool(b) => visitor.visit_bool(b),
123 v => Err(DecodeError::TypeError {
124 expected: MaterializedType::Bool,
125 got: v.canonical_type(),
126 }),
127 }
128 }
129
130 fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
131 where
132 V: Visitor<'de>,
133 {
134 match &*self.value {
135 &Value::Integer(int) if int as i8 as i64 == int => visitor.visit_i8(int as i8),
136 &Value::Integer(int) => Err(DecodeError::RangeError {
137 expected: MaterializedType::I8,
138 got: int,
139 }),
140 v => Err(DecodeError::TypeError {
141 expected: MaterializedType::I8,
142 got: v.canonical_type(),
143 }),
144 }
145 }
146
147 fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
148 where
149 V: Visitor<'de>,
150 {
151 match &*self.value {
152 &Value::Integer(int) if int as i16 as i64 == int => visitor.visit_i16(int as i16),
153 &Value::Integer(int) => Err(DecodeError::RangeError {
154 expected: MaterializedType::I16,
155 got: int,
156 }),
157 v => Err(DecodeError::TypeError {
158 expected: MaterializedType::I16,
159 got: v.canonical_type(),
160 }),
161 }
162 }
163
164 fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
165 where
166 V: Visitor<'de>,
167 {
168 match &*self.value {
169 &Value::Integer(int) if int as i32 as i64 == int => visitor.visit_i32(int as i32),
170 &Value::Integer(int) => Err(DecodeError::RangeError {
171 expected: MaterializedType::I32,
172 got: int,
173 }),
174 v => Err(DecodeError::TypeError {
175 expected: MaterializedType::I32,
176 got: v.canonical_type(),
177 }),
178 }
179 }
180
181 fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
182 where
183 V: Visitor<'de>,
184 {
185 match &*self.value {
186 &Value::Integer(int) => visitor.visit_i64(int),
187 v => Err(DecodeError::TypeError {
188 expected: MaterializedType::I64,
189 got: v.canonical_type(),
190 }),
191 }
192 }
193
194 fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
195 where
196 V: Visitor<'de>,
197 {
198 match &*self.value {
199 &Value::Integer(int) if int as u8 as i64 == int => visitor.visit_u8(int as u8),
200 &Value::Integer(int) => Err(DecodeError::RangeError {
201 expected: MaterializedType::U8,
202 got: int,
203 }),
204 v => Err(DecodeError::TypeError {
205 expected: MaterializedType::U8,
206 got: v.canonical_type(),
207 }),
208 }
209 }
210
211 fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
212 where
213 V: Visitor<'de>,
214 {
215 match &*self.value {
216 &Value::Integer(int) if int as u16 as i64 == int => visitor.visit_u16(int as u16),
217 &Value::Integer(int) => Err(DecodeError::RangeError {
218 expected: MaterializedType::U16,
219 got: int,
220 }),
221 v => Err(DecodeError::TypeError {
222 expected: MaterializedType::U16,
223 got: v.canonical_type(),
224 }),
225 }
226 }
227
228 fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
229 where
230 V: Visitor<'de>,
231 {
232 match &*self.value {
233 &Value::Integer(int) if int as u32 as i64 == int => visitor.visit_u32(int as u32),
234 &Value::Integer(int) => Err(DecodeError::RangeError {
235 expected: MaterializedType::U32,
236 got: int,
237 }),
238 v => Err(DecodeError::TypeError {
239 expected: MaterializedType::U32,
240 got: v.canonical_type(),
241 }),
242 }
243 }
244
245 fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
246 where
247 V: Visitor<'de>,
248 {
249 match &*self.value {
250 &Value::Integer(int) if int as u64 as i64 == int => visitor.visit_u64(int as u64),
251 &Value::Integer(int) => Err(DecodeError::RangeError {
252 expected: MaterializedType::U64,
253 got: int,
254 }),
255 v => Err(DecodeError::TypeError {
256 expected: MaterializedType::U64,
257 got: v.canonical_type(),
258 }),
259 }
260 }
261
262 fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
263 where
264 V: Visitor<'de>,
265 {
266 match &*self.value {
267 &Value::Integer(int) if int as f32 as i64 == int => visitor.visit_f32(int as f32),
268 &Value::Integer(int) => Err(DecodeError::RangeError {
269 expected: MaterializedType::F32,
270 got: int,
271 }),
272 &Value::Float(float) => visitor.visit_f32(float as f32),
273 v => Err(DecodeError::TypeError {
274 expected: MaterializedType::F32,
275 got: v.canonical_type(),
276 }),
277 }
278 }
279
280 fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
281 where
282 V: Visitor<'de>,
283 {
284 match &*self.value {
285 &Value::Integer(int) if int as f64 as i64 == int => visitor.visit_f64(int as f64),
286 &Value::Integer(int) => Err(DecodeError::RangeError {
287 expected: MaterializedType::F64,
288 got: int,
289 }),
290 &Value::Float(float) => visitor.visit_f64(float),
291 v => Err(DecodeError::TypeError {
292 expected: MaterializedType::F64,
293 got: v.canonical_type(),
294 }),
295 }
296 }
297
298 fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
299 where
300 V: Visitor<'de>,
301 {
302 match &*self.value {
303 Value::Text(s) if s.len() == 1 => {
304 visitor.visit_char(s.chars().next().expect("non-empty strings"))
305 }
306 v => Err(DecodeError::TypeError {
307 expected: MaterializedType::Char,
308 got: v.canonical_type(),
309 }),
310 }
311 }
312
313 fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
314 where
315 V: Visitor<'de>,
316 {
317 match &*self.value {
318 Value::Text(s) => visitor.visit_str(s),
319 v => Err(DecodeError::TypeError {
320 expected: MaterializedType::String,
321 got: v.canonical_type(),
322 }),
323 }
324 }
325
326 fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
327 where
328 V: Visitor<'de>,
329 {
330 self.deserialize_str(visitor)
331 }
332
333 fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>
334 where
335 V: Visitor<'de>,
336 {
337 match &*self.value {
338 Value::List(list) => {
339 let bytes = list
340 .iter()
341 .map(|item| match item {
342 &Value::Integer(int) if int as u8 as i64 == int => Ok(int as u8),
343 &Value::Integer(int) => Err(DecodeError::RangeError {
344 expected: MaterializedType::U8,
345 got: int,
346 }),
347 v => Err(DecodeError::TypeError {
348 expected: MaterializedType::U8,
349 got: v.canonical_type(),
350 }),
351 })
352 .collect::<Result<Vec<_>, _>>()?;
353
354 visitor.visit_byte_buf(bytes)
355 }
356 v => Err(DecodeError::TypeError {
357 expected: MaterializedType::Bytes,
358 got: v.canonical_type(),
359 }),
360 }
361 }
362
363 fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error>
364 where
365 V: Visitor<'de>,
366 {
367 self.deserialize_bytes(visitor)
368 }
369
370 fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
371 where
372 V: Visitor<'de>,
373 {
374 match &*self.value {
375 Value::Null => visitor.visit_none(),
376 _ => visitor.visit_some(Self { value: self.value }),
377 }
378 }
379
380 fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
381 where
382 V: Visitor<'de>,
383 {
384 match &*self.value {
385 Value::Null => visitor.visit_unit(),
386 v => Err(DecodeError::TypeError {
387 expected: MaterializedType::Unit,
388 got: v.canonical_type(),
389 }),
390 }
391 }
392
393 fn deserialize_unit_struct<V>(
394 self,
395 _name: &'static str,
396 visitor: V,
397 ) -> Result<V::Value, Self::Error>
398 where
399 V: Visitor<'de>,
400 {
401 self.deserialize_unit(visitor)
402 }
403
404 fn deserialize_newtype_struct<V>(
405 self,
406 _name: &'static str,
407 visitor: V,
408 ) -> Result<V::Value, Self::Error>
409 where
410 V: Visitor<'de>,
411 {
412 visitor.visit_newtype_struct(self)
413 }
414
415 fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
416 where
417 V: Visitor<'de>,
418 {
419 match &*self.value {
420 Value::List(list) => {
421 let values = list.iter().map(|item| Self {
422 value: Cow::Owned(item.clone()),
423 });
424 visitor.visit_seq(SeqDeserializer::new(values))
425 }
426 v => Err(DecodeError::TypeError {
427 expected: MaterializedType::List,
428 got: v.canonical_type(),
429 }),
430 }
431 }
432
433 fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
434 where
435 V: Visitor<'de>,
436 {
437 match &*self.value {
438 Value::List(list) if list.len() == len => self.deserialize_seq(visitor),
439 Value::List(list) => Err(DecodeError::LengthMismatch {
440 expected: len,
441 got: list.len(),
442 }),
443 v => Err(DecodeError::TypeError {
444 expected: MaterializedType::List,
445 got: v.canonical_type(),
446 }),
447 }
448 }
449
450 fn deserialize_tuple_struct<V>(
451 self,
452 _name: &'static str,
453 len: usize,
454 visitor: V,
455 ) -> Result<V::Value, Self::Error>
456 where
457 V: Visitor<'de>,
458 {
459 self.deserialize_tuple(len, visitor)
460 }
461
462 fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
463 where
464 V: Visitor<'de>,
465 {
466 match &*self.value {
467 Value::Map(dict) => {
468 let values = dict.iter().map(|(key, item)| {
469 (
470 Self {
471 value: Cow::Owned(Value::Text(key.clone())),
472 },
473 Self {
474 value: Cow::Owned(item.clone()),
475 },
476 )
477 });
478 visitor.visit_map(MapDeserializer::new(values))
479 }
480 v => Err(DecodeError::TypeError {
481 expected: MaterializedType::Map,
482 got: v.canonical_type(),
483 }),
484 }
485 }
486
487 fn deserialize_struct<V>(
488 self,
489 _name: &'static str,
490 _fields: &'static [&'static str],
491 visitor: V,
492 ) -> Result<V::Value, Self::Error>
493 where
494 V: Visitor<'de>,
495 {
496 self.deserialize_map(visitor)
497 }
498
499 fn deserialize_enum<V>(
500 self,
501 _name: &'static str,
502 _variants: &'static [&'static str],
503 visitor: V,
504 ) -> Result<V::Value, Self::Error>
505 where
506 V: Visitor<'de>,
507 {
508 match &*self.value {
509 Value::Text(string) => visitor.visit_enum(StrDeserializer::new(string)),
510 Value::Map(dict) => {
511 let values = dict.iter().map(|(key, item)| {
512 (
513 Self {
514 value: Cow::Owned(Value::Text(key.clone())),
515 },
516 Self {
517 value: Cow::Owned(item.clone()),
518 },
519 )
520 });
521 visitor.visit_enum(MapAccessDeserializer::new(MapDeserializer::new(values)))
522 }
523 v => Err(DecodeError::TypeError {
524 expected: MaterializedType::Enum,
525 got: v.canonical_type(),
526 }),
527 }
528 }
529
530 fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error>
531 where
532 V: Visitor<'de>,
533 {
534 self.deserialize_str(visitor)
535 }
536
537 fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
538 where
539 V: Visitor<'de>,
540 {
541 self.deserialize_any(visitor)
542 }
543}