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