Skip to main content

qdrant_client/
serde_deser.rs

1//! Deserialize into any serde type
2//!
3//! Sourced from <https://github.com/serde-rs/json/blob/master/src/value/de.rs>
4
5use std::collections::hash_map::IntoIter;
6
7use serde::de::value::{MapDeserializer, SeqDeserializer};
8use serde::de::{
9    DeserializeSeed, EnumAccess, Expected, IntoDeserializer, Unexpected, VariantAccess, Visitor,
10};
11use serde::Deserializer;
12
13use crate::qdrant::value::Kind;
14use crate::qdrant::{Struct, Value};
15
16#[derive(PartialEq, Eq, Clone)]
17pub enum DeserPayloadError {
18    Error(String),
19    IntegerConversion { got: i64, max: i64 },
20}
21
22impl std::fmt::Debug for DeserPayloadError {
23    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
24        match self {
25            DeserPayloadError::Error(error) => write!(f, "{error}"),
26            DeserPayloadError::IntegerConversion { got, max } => {
27                write!(f, "Overflowing integer conversion: {got} > {max}")
28            }
29        }
30    }
31}
32
33impl std::fmt::Display for DeserPayloadError {
34    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
35        write!(f, "{self:?}")
36    }
37}
38
39impl std::error::Error for DeserPayloadError {}
40
41impl serde::de::Error for DeserPayloadError {
42    fn custom<T>(msg: T) -> Self
43    where
44        T: std::fmt::Display,
45    {
46        Self::Error(msg.to_string())
47    }
48}
49
50impl<'de> IntoDeserializer<'de, DeserPayloadError> for Struct {
51    type Deserializer = MapDeserializer<'de, IntoIter<String, Value>, DeserPayloadError>;
52
53    #[inline]
54    fn into_deserializer(self) -> Self::Deserializer {
55        MapDeserializer::new(self.fields.into_iter())
56    }
57}
58
59impl<'de> IntoDeserializer<'de, DeserPayloadError> for Value {
60    type Deserializer = Self;
61
62    #[inline]
63    fn into_deserializer(self) -> Self::Deserializer {
64        self
65    }
66}
67
68macro_rules! deserialize_number {
69    ($method:ident,$visitorfn:ident,$numsize:ident) => {
70        fn $method<V>(self, visitor: V) -> Result<V::Value, DeserPayloadError>
71        where
72            V: Visitor<'de>,
73        {
74            match self.kind.as_ref() {
75                Some(Kind::IntegerValue(n)) => {
76                    visitor.$visitorfn($numsize::try_from(*n).map_err(|_| {
77                        DeserPayloadError::IntegerConversion {
78                            got: *n,
79                            max: $numsize::MAX as i64,
80                        }
81                    })?)
82                }
83                _ => Err(self.invalid_type(&visitor)),
84            }
85        }
86    };
87}
88
89fn visit_array<'de, V>(array: Vec<Value>, visitor: V) -> Result<V::Value, DeserPayloadError>
90where
91    V: Visitor<'de>,
92{
93    let mut deserializer = SeqDeserializer::new(array.into_iter());
94    let seq = visitor.visit_seq(&mut deserializer)?;
95    deserializer.end()?;
96    Ok(seq)
97}
98
99impl<'de> Deserializer<'de> for Value {
100    type Error = DeserPayloadError;
101
102    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
103    where
104        V: serde::de::Visitor<'de>,
105    {
106        match self.kind {
107            Some(kind) => match kind {
108                Kind::NullValue(_) => visitor.visit_unit(),
109                Kind::DoubleValue(double) => visitor.visit_f64(double),
110                Kind::IntegerValue(n) => visitor.visit_i64(n),
111                Kind::StringValue(s) => visitor.visit_string(s),
112                Kind::BoolValue(b) => visitor.visit_bool(b),
113                Kind::StructValue(s) => s.into_deserializer().deserialize_any(visitor),
114                Kind::ListValue(list_value) => visit_array(list_value.values, visitor),
115            },
116            None => Err(self.invalid_type(&visitor)),
117        }
118    }
119
120    fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
121    where
122        V: serde::de::Visitor<'de>,
123    {
124        match self.kind {
125            Some(Kind::BoolValue(b)) => visitor.visit_bool(b),
126            _ => Err(self.invalid_type(&visitor)),
127        }
128    }
129
130    deserialize_number!(deserialize_i8, visit_i8, i8);
131    deserialize_number!(deserialize_i16, visit_i16, i16);
132    deserialize_number!(deserialize_i32, visit_i32, i32);
133    deserialize_number!(deserialize_i64, visit_i64, i64);
134    deserialize_number!(deserialize_u8, visit_u8, u8);
135    deserialize_number!(deserialize_u16, visit_u16, u16);
136    deserialize_number!(deserialize_u32, visit_u32, u32);
137    deserialize_number!(deserialize_u64, visit_u64, u64);
138
139    fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, DeserPayloadError>
140    where
141        V: Visitor<'de>,
142    {
143        match self.kind.as_ref() {
144            Some(Kind::DoubleValue(n)) => visitor.visit_f32(*n as f32),
145            // Whole numbers are stored as integers, accept them for float fields too
146            Some(Kind::IntegerValue(n)) => visitor.visit_i64(*n),
147            _ => Err(self.invalid_type(&visitor)),
148        }
149    }
150
151    fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, DeserPayloadError>
152    where
153        V: Visitor<'de>,
154    {
155        match self.kind.as_ref() {
156            Some(Kind::DoubleValue(n)) => visitor.visit_f64(*n),
157            // Whole numbers are stored as integers, accept them for float fields too
158            Some(Kind::IntegerValue(n)) => visitor.visit_i64(*n),
159            _ => Err(self.invalid_type(&visitor)),
160        }
161    }
162
163    fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
164    where
165        V: serde::de::Visitor<'de>,
166    {
167        self.deserialize_string(visitor)
168    }
169
170    fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
171    where
172        V: serde::de::Visitor<'de>,
173    {
174        match self.kind {
175            Some(Kind::StringValue(b)) => visitor.visit_str(&b),
176            _ => Err(self.invalid_type(&visitor)),
177        }
178    }
179
180    fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
181    where
182        V: serde::de::Visitor<'de>,
183    {
184        match self.kind {
185            Some(Kind::StringValue(b)) => visitor.visit_string(b),
186            _ => Err(self.invalid_type(&visitor)),
187        }
188    }
189
190    fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>
191    where
192        V: serde::de::Visitor<'de>,
193    {
194        self.deserialize_byte_buf(visitor)
195    }
196
197    fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error>
198    where
199        V: serde::de::Visitor<'de>,
200    {
201        match self.kind {
202            Some(Kind::StringValue(b)) => visitor.visit_string(b),
203            Some(Kind::ListValue(b)) => visit_array(b.values, visitor),
204            _ => Err(self.invalid_type(&visitor)),
205        }
206    }
207
208    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
209    where
210        V: serde::de::Visitor<'de>,
211    {
212        if self.kind.is_none() || matches!(self.kind, Some(Kind::NullValue(..))) {
213            return visitor.visit_none();
214        }
215
216        visitor.visit_some(self)
217    }
218
219    fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
220    where
221        V: serde::de::Visitor<'de>,
222    {
223        match &self.kind {
224            Some(Kind::NullValue(_)) => visitor.visit_unit(),
225            _ => Err(self.invalid_type(&visitor)),
226        }
227    }
228
229    fn deserialize_unit_struct<V>(
230        self,
231        _name: &'static str,
232        visitor: V,
233    ) -> Result<V::Value, Self::Error>
234    where
235        V: serde::de::Visitor<'de>,
236    {
237        self.deserialize_unit(visitor)
238    }
239
240    fn deserialize_newtype_struct<V>(
241        self,
242        _name: &'static str,
243        visitor: V,
244    ) -> Result<V::Value, Self::Error>
245    where
246        V: serde::de::Visitor<'de>,
247    {
248        visitor.visit_newtype_struct(self)
249    }
250
251    fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
252    where
253        V: serde::de::Visitor<'de>,
254    {
255        match self.kind {
256            Some(Kind::ListValue(list)) => visit_array(list.values, visitor),
257            _ => Err(self.invalid_type(&visitor)),
258        }
259    }
260
261    fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
262    where
263        V: serde::de::Visitor<'de>,
264    {
265        self.deserialize_seq(visitor)
266    }
267
268    fn deserialize_tuple_struct<V>(
269        self,
270        _name: &'static str,
271        _len: usize,
272        visitor: V,
273    ) -> Result<V::Value, Self::Error>
274    where
275        V: serde::de::Visitor<'de>,
276    {
277        self.deserialize_seq(visitor)
278    }
279
280    fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
281    where
282        V: serde::de::Visitor<'de>,
283    {
284        match self.kind {
285            Some(Kind::StructValue(r#struct)) => {
286                r#struct.into_deserializer().deserialize_any(visitor)
287            }
288            _ => Err(self.invalid_type(&visitor)),
289        }
290    }
291
292    fn deserialize_struct<V>(
293        self,
294        _name: &'static str,
295        _fields: &'static [&'static str],
296        visitor: V,
297    ) -> Result<V::Value, Self::Error>
298    where
299        V: serde::de::Visitor<'de>,
300    {
301        match self.kind {
302            Some(k) => match k {
303                Kind::StructValue(r#struct) => {
304                    r#struct.into_deserializer().deserialize_any(visitor)
305                }
306                Kind::ListValue(list) => visit_array(list.values, visitor),
307                _ => Err(Self::invalid_type_from_kind(&k, &visitor)),
308            },
309            None => Err(self.invalid_type(&visitor)),
310        }
311    }
312
313    fn deserialize_enum<V>(
314        self,
315        name: &'static str,
316        variants: &'static [&'static str],
317        visitor: V,
318    ) -> Result<V::Value, Self::Error>
319    where
320        V: serde::de::Visitor<'de>,
321    {
322        match self.kind {
323            Some(k) => match k {
324                Kind::StructValue(r#struct) => r#struct
325                    .into_deserializer()
326                    .deserialize_enum(name, variants, visitor),
327                Kind::StringValue(variant) => visitor.visit_enum(EnumDeserializer { variant }),
328                _ => Err(Self::invalid_type_from_kind(&k, &visitor)),
329            },
330            None => Err(self.invalid_type(&visitor)),
331        }
332    }
333
334    fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error>
335    where
336        V: serde::de::Visitor<'de>,
337    {
338        self.deserialize_str(visitor)
339    }
340
341    fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
342    where
343        V: serde::de::Visitor<'de>,
344    {
345        drop(self);
346        visitor.visit_unit()
347    }
348
349    fn deserialize_i128<V>(self, visitor: V) -> Result<V::Value, Self::Error>
350    where
351        V: Visitor<'de>,
352    {
353        let _ = visitor;
354        Err(serde::de::Error::custom("i128 is not supported"))
355    }
356
357    fn deserialize_u128<V>(self, visitor: V) -> Result<V::Value, Self::Error>
358    where
359        V: Visitor<'de>,
360    {
361        let _ = visitor;
362        Err(serde::de::Error::custom("u128 is not supported"))
363    }
364}
365
366struct EnumDeserializer {
367    variant: String,
368}
369
370impl<'de> EnumAccess<'de> for EnumDeserializer {
371    type Error = DeserPayloadError;
372    type Variant = VariantDeserializer;
373
374    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, VariantDeserializer), Self::Error>
375    where
376        V: DeserializeSeed<'de>,
377    {
378        let variant = self.variant.into_deserializer();
379        let visitor = VariantDeserializer;
380        seed.deserialize(variant).map(|v| (v, visitor))
381    }
382}
383
384struct VariantDeserializer;
385
386impl<'de> VariantAccess<'de> for VariantDeserializer {
387    type Error = DeserPayloadError;
388
389    fn unit_variant(self) -> Result<(), Self::Error> {
390        Ok(())
391    }
392
393    fn newtype_variant_seed<T>(self, _seed: T) -> Result<T::Value, Self::Error>
394    where
395        T: DeserializeSeed<'de>,
396    {
397        Err(serde::de::Error::invalid_type(
398            Unexpected::UnitVariant,
399            &"newtype variant",
400        ))
401    }
402
403    fn tuple_variant<V>(self, _len: usize, _visitor: V) -> Result<V::Value, Self::Error>
404    where
405        V: Visitor<'de>,
406    {
407        Err(serde::de::Error::invalid_type(
408            Unexpected::UnitVariant,
409            &"tuple variant",
410        ))
411    }
412
413    fn struct_variant<V>(
414        self,
415        _fields: &'static [&'static str],
416        _visitor: V,
417    ) -> Result<V::Value, Self::Error>
418    where
419        V: Visitor<'de>,
420    {
421        Err(serde::de::Error::invalid_type(
422            Unexpected::UnitVariant,
423            &"struct variant",
424        ))
425    }
426}
427
428impl Value {
429    #[cold]
430    fn invalid_type<E>(&self, exp: &dyn Expected) -> E
431    where
432        E: serde::de::Error,
433    {
434        serde::de::Error::invalid_type(self.unexpected(), exp)
435    }
436
437    #[cold]
438    fn unexpected<'a>(&'a self) -> Unexpected<'a> {
439        match self.kind.as_ref() {
440            Some(k) => match k {
441                Kind::NullValue(_) => Unexpected::Unit,
442                Kind::DoubleValue(d) => Unexpected::Float(*d),
443                Kind::IntegerValue(i) => Unexpected::Signed(*i),
444                Kind::StringValue(s) => Unexpected::Str(s),
445                Kind::BoolValue(b) => Unexpected::Bool(*b),
446                Kind::StructValue(_) => Unexpected::Map,
447                Kind::ListValue(_) => Unexpected::Seq,
448            },
449            None => Unexpected::Unit,
450        }
451    }
452
453    #[cold]
454    fn invalid_type_from_kind<E>(kind: &Kind, exp: &dyn Expected) -> E
455    where
456        E: serde::de::Error,
457    {
458        serde::de::Error::invalid_type(Self::unexpected_kind(kind), exp)
459    }
460
461    #[cold]
462    fn unexpected_kind<'a>(kind: &'a Kind) -> Unexpected<'a> {
463        match kind {
464            Kind::NullValue(_) => Unexpected::Unit,
465            Kind::DoubleValue(d) => Unexpected::Float(*d),
466            Kind::IntegerValue(i) => Unexpected::Signed(*i),
467            Kind::StringValue(s) => Unexpected::Str(s),
468            Kind::BoolValue(b) => Unexpected::Bool(*b),
469            Kind::StructValue(_) => Unexpected::Map,
470            Kind::ListValue(_) => Unexpected::Seq,
471        }
472    }
473}
474
475#[cfg(test)]
476mod test {
477    use std::collections::{BTreeMap, HashMap};
478
479    use serde::{Deserialize, Serialize};
480    use serde_json::json;
481
482    use crate::serde_deser::DeserPayloadError;
483    use crate::Payload;
484
485    #[test]
486    fn test_json_deser() {
487        #[derive(Deserialize, Serialize, Eq, PartialEq, Debug)]
488        struct S {
489            some_string: String,
490            some_bool: bool,
491            some_int: i32,
492            some_seq: Vec<String>,
493            some_obj: HashMap<String, String>,
494            tuple: (String, u32),
495            #[allow(clippy::type_complexity)]
496            tuple_map: BTreeMap<String, (String, u32, Vec<(u32, String)>)>,
497        }
498
499        let value = S {
500            some_string: "Bar".into(),
501            some_bool: true,
502            some_int: 12,
503            some_seq: vec!["elem1".into(), "elem2".into()],
504            some_obj: HashMap::from([("key".into(), "value".into())]),
505            tuple: ("abc".to_string(), 42),
506            tuple_map: BTreeMap::from([
507                (
508                    "key1".to_string(),
509                    ("42".to_string(), 13, vec![(43, "abc".to_string())]),
510                ),
511                (
512                    "key2".to_string(),
513                    ("rust".to_string(), 91, vec![(84, "python".to_string())]),
514                ),
515            ]),
516        };
517
518        let json_value = serde_json::to_value(&value).unwrap();
519        let payload: Payload = json_value.try_into().unwrap();
520        let deserialized_value: S = payload.deserialize().unwrap();
521
522        assert_eq!(value, deserialized_value)
523    }
524
525    fn make_payload(val: serde_json::Value) -> Payload {
526        val.try_into().expect(
527            "Can only make a json object to Payload. This is a bug in the unit test itself.",
528        )
529    }
530
531    #[test]
532    fn test_integer_conversion() {
533        let payload = make_payload(json!({"integer": u32::MAX}));
534
535        #[derive(Deserialize, Clone)]
536        #[allow(dead_code)]
537        struct DstU8 {
538            integer: u8,
539        }
540
541        // Check fail
542        let got: Result<DstU8, _> = payload.clone().deserialize();
543        assert_eq!(
544            got.err().unwrap().as_payload_deserialization().unwrap(),
545            &DeserPayloadError::IntegerConversion {
546                got: u32::MAX as i64,
547                max: u8::MAX as i64
548            }
549        );
550
551        #[derive(Deserialize, Debug, PartialEq)]
552        #[allow(dead_code)]
553        struct DstU32 {
554            integer: u32,
555        }
556
557        // Check success
558        let got: Result<DstU32, _> = payload.deserialize();
559        assert_eq!(got.unwrap(), DstU32 { integer: u32::MAX });
560    }
561
562    #[test]
563    fn test_nested() {
564        let payload = make_payload(json!({"number": 42, "data": {"text": "abc", "num": 99}}));
565
566        #[derive(Deserialize)]
567        #[allow(dead_code)]
568        struct Dst {
569            number: u32,
570            data: DstData,
571        }
572
573        #[derive(Deserialize)]
574        #[allow(dead_code)]
575        struct DstData {
576            text: String,
577            num: u8,
578        }
579
580        let dst: Dst = payload.deserialize().unwrap();
581        assert_eq!(dst.number, 42);
582        assert_eq!(dst.data.num, 99);
583        assert_eq!(dst.data.text, "abc");
584    }
585
586    #[test]
587    fn test_tuple() {
588        let payload = make_payload(json!({"number": 42, "seq": [1,2,3]}));
589
590        #[derive(Deserialize)]
591        #[allow(dead_code)]
592        struct Dst {
593            number: u32,
594            seq: (u8, u8, u8),
595        }
596
597        let dst: Dst = payload.clone().deserialize().unwrap();
598        assert_eq!(dst.seq, (1, 2, 3));
599
600        #[derive(Deserialize)]
601        #[allow(dead_code)]
602        struct DstTooShort {
603            number: u32,
604            seq: (u8, u8),
605        }
606
607        let dst: Result<DstTooShort, _> = payload.clone().deserialize();
608        assert!(dst.is_err());
609
610        #[derive(Deserialize)]
611        #[allow(dead_code)]
612        struct DstTooLong {
613            number: u32,
614            seq: (u8, u8, u8, u8),
615        }
616
617        let dst: Result<DstTooLong, _> = payload.deserialize();
618        assert!(dst.is_err());
619    }
620
621    #[test]
622    fn test_enum() {
623        let payload = make_payload(json!({"items": ["Major","Minor","Mid"]}));
624
625        #[derive(Deserialize, Debug)]
626        #[allow(dead_code)]
627        struct Dst {
628            items: Vec<DstEnum>,
629        }
630
631        #[derive(Deserialize, PartialEq, Debug)]
632        #[allow(dead_code)]
633        enum DstEnum {
634            Major,
635            Minor,
636            Mid,
637            SomewhereElse,
638        }
639
640        let dst: Dst = payload.deserialize().unwrap();
641        assert_eq!(
642            dst.items,
643            vec![DstEnum::Major, DstEnum::Minor, DstEnum::Mid]
644        );
645
646        let payload = make_payload(json!({"items": ["Major","Minor","Middle"]})); // "Middle" is no enum variant.
647        let dst: Result<Dst, _> = payload.deserialize();
648        assert!(dst.is_err())
649    }
650
651    #[test]
652    fn test_enum_tuple_struct() {
653        let payload = make_payload(json!({"items": ["Major",32,true]}));
654
655        #[derive(Deserialize, Debug)]
656        #[allow(dead_code)]
657        struct Dst {
658            items: Vec<DstEnum>,
659        }
660
661        #[derive(Deserialize, PartialEq, Debug)]
662        #[allow(dead_code)]
663        #[serde(untagged)]
664        enum DstEnum {
665            Str(String),
666            Num(i32),
667            Bool(bool),
668        }
669
670        let dst: Dst = payload.deserialize().unwrap();
671        assert_eq!(
672            dst.items,
673            vec![
674                DstEnum::Str("Major".to_string()),
675                DstEnum::Num(32),
676                DstEnum::Bool(true)
677            ]
678        );
679    }
680
681    #[test]
682    fn test_enum_struct() {
683        let payload = make_payload(json!({"items": [{"key": "Major"},{"other": 32},true]}));
684
685        #[derive(Deserialize, Debug)]
686        #[allow(dead_code)]
687        struct Dst {
688            items: Vec<DstEnum>,
689        }
690
691        #[derive(Deserialize, PartialEq, Debug)]
692        #[allow(dead_code)]
693        #[serde(untagged)]
694        enum DstEnum {
695            First { key: String },
696            Second { other: u32 },
697            Bool(bool),
698        }
699
700        let dst: Dst = payload.deserialize().unwrap();
701        assert_eq!(
702            dst.items,
703            vec![
704                DstEnum::First {
705                    key: "Major".to_string()
706                },
707                DstEnum::Second { other: 32 },
708                DstEnum::Bool(true)
709            ]
710        );
711
712        let payload_direct =
713            make_payload(json!({"item": {"key": "Major"}, "other": {"other": 32}, "third": false}));
714
715        #[derive(Deserialize, Debug)]
716        #[allow(dead_code)]
717        struct Dst2 {
718            item: DstEnum,
719            other: DstEnum,
720            third: DstEnum,
721        }
722
723        let dst: Dst2 = payload_direct.deserialize().unwrap();
724        assert_eq!(
725            dst.item,
726            DstEnum::First {
727                key: "Major".to_string()
728            }
729        );
730        assert_eq!(dst.other, DstEnum::Second { other: 32 });
731        assert_eq!(dst.third, DstEnum::Bool(false));
732
733        let dst_err: Result<Dst2, _> = make_payload(
734            json!({"item": {"key2": "Major"}, "other": {"other": 32}, "third": false}),
735        )
736        .deserialize();
737        assert!(dst_err.is_err())
738    }
739
740    #[test]
741    fn test_enum_struct_tagged() {
742        let payload = make_payload(
743            json!({"items": [{"t": "First", "c": {"key": "Major"}}, {"t": "Second","c": {"other": 32}},{"t": "Bool", "c": true}]}),
744        );
745
746        #[derive(Deserialize, Debug)]
747        #[allow(dead_code)]
748        struct Dst {
749            items: Vec<DstEnum>,
750        }
751
752        #[derive(Deserialize, PartialEq, Debug)]
753        #[allow(dead_code)]
754        #[serde(tag = "t", content = "c")]
755        enum DstEnum {
756            First { key: String },
757            Second { other: u32 },
758            Bool(bool),
759        }
760
761        let dst: Dst = payload.deserialize().unwrap();
762        assert_eq!(
763            dst.items,
764            vec![
765                DstEnum::First {
766                    key: "Major".to_string()
767                },
768                DstEnum::Second { other: 32 },
769                DstEnum::Bool(true)
770            ]
771        );
772    }
773
774    #[test]
775    fn test_option() {
776        let payload = make_payload(json!({
777            "str1": "hi",
778            "int1": 32,
779            "vec1": [42]
780        }));
781
782        #[derive(Deserialize, Debug, PartialEq)]
783        #[allow(dead_code)]
784        struct Dst {
785            str1: Option<String>,
786            str2: Option<String>,
787            int1: Option<i32>,
788            #[serde(skip_serializing_if = "Option::is_none")]
789            int2: Option<i32>,
790            vec1: Option<Vec<u32>>,
791            vec2: Option<Vec<u32>>,
792        }
793
794        let dst: Dst = payload.deserialize().unwrap();
795        assert_eq!(
796            dst,
797            Dst {
798                str1: Some("hi".to_string()),
799                str2: None,
800                int1: Some(32),
801                int2: None,
802                vec1: Some(vec![42]),
803                vec2: None,
804            }
805        )
806    }
807
808    #[test]
809    fn test_other_types() {
810        let payload = make_payload(json!({
811            "bytes": [0,4,15,11,96,12],
812            "double": 0.2,
813            "null": None::<u32>,
814            "single_char": 'c',
815        }));
816
817        #[derive(Deserialize, Debug, PartialEq)]
818        #[allow(dead_code)]
819        struct Dst {
820            bytes: Vec<u8>,
821            double: f32,
822            null: (),
823            single_char: char,
824        }
825
826        let dst: Dst = payload.deserialize().unwrap();
827        assert_eq!(dst.bytes, vec![0, 4, 15, 11, 96, 12]);
828        assert_eq!(dst.double, 0.2);
829        assert_eq!(dst.single_char, 'c');
830    }
831
832    #[test]
833    fn test_integer_into_float() {
834        // Whole numbers are stored as integers, e.g. `{"price": 10}`
835        let payload = make_payload(json!({
836            "double": 10,
837            "single": -3,
838            "opt_double": 7,
839        }));
840
841        #[derive(Deserialize, Debug, PartialEq)]
842        struct Dst {
843            double: f64,
844            single: f32,
845            opt_double: Option<f64>,
846        }
847
848        let dst: Dst = payload.deserialize().unwrap();
849        assert_eq!(
850            dst,
851            Dst {
852                double: 10.0,
853                single: -3.0,
854                opt_double: Some(7.0),
855            }
856        );
857    }
858}