Skip to main content

hocon/serde/
de.rs

1//! Deserializer methods using serde
2
3use super::error::Error;
4use super::error::Result;
5use crate::Hocon;
6
7pub use super::wrappers;
8
9macro_rules! impl_deserialize_n {
10    ($method:ident, $visit:ident) => {
11        fn $method<V>(self, visitor: V) -> Result<V::Value>
12        where
13            V: serde::de::Visitor<'de>,
14        {
15            visitor.$visit({
16                let value = self
17                    .read
18                    .get_attribute_value(&self.current_field)
19                    .ok_or_else(|| Error {
20                        message: format!("missing integer for field \"{}\"", self.current_field),
21                    })?
22                    .clone();
23                value
24                    .as_i64()
25                    .or_else(|| value.as_bytes().map(|v| v as i64))
26                    .ok_or_else(|| Error {
27                        message: format!(
28                            "Invalid type for field \"{}\", expected integer",
29                            self.current_field
30                        ),
31                    })?
32            })
33        }
34    };
35    ($type:ty, $method:ident, $visit:ident) => {
36        fn $method<V>(self, visitor: V) -> Result<V::Value>
37        where
38            V: serde::de::Visitor<'de>,
39        {
40            visitor.$visit({
41                let value = self
42                    .read
43                    .get_attribute_value(&self.current_field)
44                    .ok_or_else(|| Error {
45                        message: format!("missing integer for field \"{}\"", self.current_field),
46                    })?
47                    .clone();
48                value
49                    .as_i64()
50                    .or_else(|| value.as_bytes().map(|v| v as i64))
51                    .ok_or_else(|| Error {
52                        message: format!(
53                            "Invalid type for field \"{}\", expected integer",
54                            self.current_field
55                        ),
56                    })? as $type
57            })
58        }
59    };
60}
61macro_rules! impl_deserialize_f {
62    ($method:ident, $visit:ident) => {
63        fn $method<V>(self, visitor: V) -> Result<V::Value>
64        where
65            V: serde::de::Visitor<'de>,
66        {
67            visitor.$visit({
68                let value = self
69                    .read
70                    .get_attribute_value(&self.current_field)
71                    .ok_or_else(|| Error {
72                        message: format!("missing float for field \"{}\"", self.current_field),
73                    })?
74                    .clone();
75                value
76                    .as_f64()
77                    .or_else(|| value.as_bytes().map(|v| v as f64))
78                    .ok_or_else(|| Error {
79                        message: format!(
80                            "Invalid type for field \"{}\", expected float",
81                            self.current_field
82                        ),
83                    })?
84            })
85        }
86    };
87    ($type:ty, $method:ident, $visit:ident) => {
88        fn $method<V>(self, visitor: V) -> Result<V::Value>
89        where
90            V: serde::de::Visitor<'de>,
91        {
92            visitor.$visit({
93                let value = self
94                    .read
95                    .get_attribute_value(&self.current_field)
96                    .ok_or_else(|| Error {
97                        message: format!("missing float for field \"{}\"", self.current_field),
98                    })?
99                    .clone();
100                value
101                    .as_f64()
102                    .or_else(|| value.as_bytes().map(|v| v as f64))
103                    .ok_or_else(|| Error {
104                        message: format!(
105                            "Invalid type for field \"{}\", expected float",
106                            self.current_field
107                        ),
108                    })? as $type
109            })
110        }
111    };
112}
113
114#[derive(Debug)]
115enum Index {
116    String(String),
117    Number(usize),
118    None,
119}
120
121impl std::fmt::Display for Index {
122    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
123        match self {
124            Index::String(field) => write!(f, "{}", field),
125            Index::Number(field) => write!(f, "{}", field),
126            Index::None => write!(f, ""),
127        }
128    }
129}
130
131trait Read {
132    fn get_attribute_value(&self, index: &Index) -> Option<&Hocon>;
133    fn get_keys(&self) -> Vec<String>;
134}
135
136struct HoconRead {
137    hocon: Hocon,
138}
139impl HoconRead {
140    fn new(hocon: Hocon) -> Self {
141        HoconRead { hocon }
142    }
143}
144impl Read for HoconRead {
145    fn get_attribute_value(&self, index: &Index) -> Option<&Hocon> {
146        match index {
147            Index::String(key) => match &self.hocon[key.as_ref()] {
148                Hocon::BadValue(_) => None,
149                v => Some(v),
150            },
151            Index::Number(key) => match &self.hocon[*key] {
152                Hocon::BadValue(_) => None,
153                v => Some(v),
154            },
155            _ => None,
156        }
157    }
158
159    fn get_keys(&self) -> Vec<String> {
160        match &self.hocon {
161            Hocon::Hash(map) => map.keys().cloned().collect(),
162            _ => unreachable!(),
163        }
164    }
165}
166
167#[derive(Debug)]
168struct Deserializer<R> {
169    read: R,
170    current_field: Index,
171    as_key: bool,
172}
173impl<R> Deserializer<R>
174where
175    R: Read,
176{
177    pub fn new(read: R) -> Self {
178        Deserializer {
179            read,
180            current_field: Index::None,
181            as_key: false,
182        }
183    }
184}
185
186impl<'de, R: Read> serde::de::Deserializer<'de> for &mut Deserializer<R> {
187    type Error = Error;
188
189    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
190    where
191        V: serde::de::Visitor<'de>,
192    {
193        if self.as_key {
194            self.deserialize_identifier(visitor)
195        } else {
196            let f: Hocon = self
197                .read
198                .get_attribute_value(&self.current_field)
199                .ok_or_else(|| Error {
200                    message: format!("missing value for field \"{}\"", self.current_field),
201                })?
202                .clone();
203            match f {
204                Hocon::Boolean(_) => self.deserialize_bool(visitor),
205                Hocon::Real(_) => self.deserialize_f64(visitor),
206                Hocon::Integer(_) => self.deserialize_i64(visitor),
207                Hocon::String(_) => self.deserialize_string(visitor),
208                Hocon::Array(_) => self.deserialize_seq(visitor),
209                Hocon::Hash(_) => self.deserialize_map(visitor),
210                Hocon::Null => self.deserialize_option(visitor),
211                Hocon::BadValue(err) => Err(Error {
212                    message: format!("error for field \"{}\": {}", self.current_field, err),
213                }),
214            }
215        }
216    }
217
218    fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
219    where
220        V: serde::de::Visitor<'de>,
221    {
222        visitor.visit_bool(
223            self.read
224                .get_attribute_value(&self.current_field)
225                .ok_or_else(|| Error {
226                    message: format!("Missing field \"{}\"", self.current_field),
227                })?
228                .clone()
229                .as_bool()
230                .ok_or_else(|| Error {
231                    message: format!(
232                        "Invalid type for field \"{}\", expected bool",
233                        self.current_field
234                    ),
235                })?,
236        )
237    }
238
239    impl_deserialize_n!(i8, deserialize_i8, visit_i8);
240    impl_deserialize_n!(i16, deserialize_i16, visit_i16);
241    impl_deserialize_n!(i32, deserialize_i32, visit_i32);
242    impl_deserialize_n!(deserialize_i64, visit_i64);
243    // impl_deserialize_n!(i64, deserialize_i64, visit_i64);
244
245    impl_deserialize_n!(u8, deserialize_u8, visit_u8);
246    impl_deserialize_n!(u16, deserialize_u16, visit_u16);
247    impl_deserialize_n!(u32, deserialize_u32, visit_u32);
248    impl_deserialize_n!(u64, deserialize_u64, visit_u64);
249
250    impl_deserialize_f!(f32, deserialize_f32, visit_f32);
251    impl_deserialize_f!(deserialize_f64, visit_f64);
252    // impl_deserialize_f!(f64, deserialize_f64, visit_f64);
253
254    fn deserialize_char<V>(self, visitor: V) -> Result<V::Value>
255    where
256        V: serde::de::Visitor<'de>,
257    {
258        visitor.visit_char(
259            self.read
260                .get_attribute_value(&self.current_field)
261                .ok_or_else(|| Error {
262                    message: format!("missing char for field \"{}\"", self.current_field),
263                })?
264                .clone()
265                .as_string()
266                .ok_or_else(|| Error {
267                    message: format!("missing char for field \"{}\"", self.current_field),
268                })?
269                .parse::<char>()
270                .map_err(|_| Error {
271                    message: format!("Expected char type for field \"{}\"", self.current_field),
272                })?,
273        )
274    }
275
276    fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
277    where
278        V: serde::de::Visitor<'de>,
279    {
280        if self.as_key {
281            match &self.current_field {
282                Index::String(key) => visitor.visit_str(key),
283                _ => visitor.visit_str(""),
284            }
285        } else if let Some(field) = self.read.get_attribute_value(&self.current_field) {
286            field
287                .clone()
288                .as_string()
289                .ok_or_else(|| Error {
290                    message: format!("missing string for field \"{}\"", self.current_field),
291                })
292                .and_then(|string_field| visitor.visit_str(&string_field))
293        } else {
294            visitor.visit_str("")
295        }
296    }
297
298    fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
299    where
300        V: serde::de::Visitor<'de>,
301    {
302        self.deserialize_str(visitor)
303    }
304
305    fn deserialize_bytes<V>(self, _visitor: V) -> Result<V::Value>
306    where
307        V: serde::de::Visitor<'de>,
308    {
309        unimplemented!()
310    }
311
312    fn deserialize_byte_buf<V>(self, _visitor: V) -> Result<V::Value>
313    where
314        V: serde::de::Visitor<'de>,
315    {
316        unimplemented!()
317    }
318
319    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
320    where
321        V: serde::de::Visitor<'de>,
322    {
323        if self.read.get_attribute_value(&self.current_field).is_none() {
324            return visitor.visit_none();
325        }
326        match self
327            .read
328            .get_attribute_value(&self.current_field)
329            .ok_or_else(|| Error {
330                message: format!("missing option for field \"{}\"", self.current_field),
331            })? {
332            Hocon::Null => visitor.visit_none(),
333            _ => visitor.visit_some(self),
334        }
335    }
336
337    fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
338    where
339        V: serde::de::Visitor<'de>,
340    {
341        match self
342            .read
343            .get_attribute_value(&self.current_field)
344            .ok_or_else(|| Error {
345                message: format!("missing option for field \"{}\"", self.current_field),
346            })? {
347            Hocon::Null => visitor.visit_unit(),
348            _ => visitor.visit_unit(),
349        }
350    }
351
352    fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
353    where
354        V: serde::de::Visitor<'de>,
355    {
356        self.deserialize_unit(visitor)
357    }
358
359    fn deserialize_newtype_struct<V>(self, _name: &str, visitor: V) -> Result<V::Value>
360    where
361        V: serde::de::Visitor<'de>,
362    {
363        visitor.visit_newtype_struct(self)
364    }
365
366    fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
367    where
368        V: serde::de::Visitor<'de>,
369    {
370        let list = self
371            .read
372            .get_attribute_value(&self.current_field)
373            .ok_or_else(|| Error {
374                message: format!("missing sequence for field \"{}\"", self.current_field),
375            })?
376            .clone();
377        let read = match list {
378            Hocon::Array(_) | Hocon::Hash(_) => HoconRead { hocon: list },
379            _ => {
380                return Err(Error {
381                    message: format!(
382                        "No sequence input found for field \"{}\"",
383                        self.current_field
384                    ),
385                });
386            }
387        };
388        let mut des = Deserializer::new(read);
389        visitor.visit_seq(SeqAccess::new(&mut des))
390    }
391
392    fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value>
393    where
394        V: serde::de::Visitor<'de>,
395    {
396        let list = self
397            .read
398            .get_attribute_value(&self.current_field)
399            .ok_or_else(|| Error {
400                message: format!("missing sequence for field \"{}\"", self.current_field),
401            })?
402            .clone();
403        let read = match list {
404            Hocon::Array(_) | Hocon::Hash(_) => HoconRead { hocon: list },
405            _ => {
406                return Err(Error {
407                    message: format!(
408                        "No sequence input found for field \"{}\"",
409                        self.current_field
410                    ),
411                });
412            }
413        };
414        let mut des = Deserializer::new(read);
415        visitor.visit_seq(SeqAccess::new(&mut des))
416    }
417
418    fn deserialize_tuple_struct<V>(
419        self,
420        _name: &'static str,
421        len: usize,
422        visitor: V,
423    ) -> Result<V::Value>
424    where
425        V: serde::de::Visitor<'de>,
426    {
427        self.deserialize_tuple(len, visitor)
428    }
429
430    fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
431    where
432        V: serde::de::Visitor<'de>,
433    {
434        match self.current_field {
435            Index::None => visitor.visit_map(MapAccess::new(self, self.read.get_keys())),
436            _ => {
437                let hc = self
438                    .read
439                    .get_attribute_value(&self.current_field)
440                    .ok_or_else(|| Error {
441                        message: format!("missing struct for field \"{}\"", self.current_field),
442                    })?
443                    .clone();
444                let keys = match &hc {
445                    Hocon::Hash(hm) => hm.keys().cloned().collect(),
446                    _ => {
447                        return Err(Error {
448                            message: format!("invalid type for field \"{}\"", self.current_field),
449                        });
450                    }
451                };
452                let mut des = Deserializer::new(HoconRead::new(hc));
453                visitor.visit_map(MapAccess::new(&mut des, keys))
454            }
455        }
456    }
457
458    fn deserialize_struct<V>(
459        self,
460        _name: &'static str,
461        _fields: &'static [&'static str],
462        visitor: V,
463    ) -> Result<V::Value>
464    where
465        V: serde::de::Visitor<'de>,
466    {
467        self.deserialize_map(visitor)
468    }
469
470    fn deserialize_enum<V>(
471        self,
472        _name: &str,
473        variants: &'static [&'static str],
474        visitor: V,
475    ) -> Result<V::Value>
476    where
477        V: serde::de::Visitor<'de>,
478    {
479        let hc = self
480            .read
481            .get_attribute_value(&self.current_field)
482            .ok_or_else(|| Error {
483                message: format!("missing struct for field \"{}\"", self.current_field),
484            })?
485            .clone();
486
487        if let Index::String(s) = &self.current_field {
488            for v in variants {
489                if s == v {
490                    let reader = HoconRead::new(hc);
491                    let deserializer = &mut Deserializer::new(reader);
492                    deserializer.current_field = Index::String(String::from(s));
493                    return visitor.visit_enum(UnitVariantAccess::new(deserializer));
494                }
495            }
496        }
497
498        match &hc {
499            Hocon::String(name) => {
500                let index = Index::String(String::from(name));
501                let reader = HoconRead::new(hc);
502                let deserializer = &mut Deserializer::new(reader);
503                deserializer.current_field = index;
504                visitor.visit_enum(UnitVariantAccess::new(deserializer))
505            }
506            Hocon::Hash(variant_map) => {
507                let mut keys = variant_map.keys();
508                let first_key = keys.next().ok_or_else(|| Error {
509                    message: format!(
510                        "non unit enum variant should have enum serialized for field \"{}\"",
511                        self.current_field
512                    ),
513                })?;
514                if let Some(_other_key) = keys.next() {
515                    return Err(Error {
516                        message: format!(
517                            "non unit enum variant should have enum serialized for field \"{}\"",
518                            self.current_field
519                        ),
520                    });
521                }
522                let index = Index::String(String::from(first_key));
523                let reader = HoconRead::new(hc);
524                let deserializer = &mut Deserializer::new(reader);
525                deserializer.current_field = index;
526                visitor.visit_enum(VariantAccess::new(deserializer))
527            }
528            _ => Err(Error {
529                message: format!("invalid type for field \"{}\"", self.current_field),
530            }),
531        }
532    }
533
534    fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
535    where
536        V: serde::de::Visitor<'de>,
537    {
538        self.deserialize_str(visitor)
539    }
540
541    fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
542    where
543        V: serde::de::Visitor<'de>,
544    {
545        visitor.visit_unit()
546    }
547}
548
549struct SeqAccess<'a, R: 'a> {
550    de: &'a mut Deserializer<R>,
551    current: usize,
552}
553
554impl<'a, R: 'a> SeqAccess<'a, R> {
555    fn new(de: &'a mut Deserializer<R>) -> Self {
556        SeqAccess { de, current: 0 }
557    }
558}
559
560impl<'de, 'a, R: Read + 'a> serde::de::SeqAccess<'de> for SeqAccess<'a, R> {
561    type Error = Error;
562
563    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
564    where
565        T: serde::de::DeserializeSeed<'de>,
566    {
567        self.de.current_field = Index::Number(self.current);
568        self.current += 1;
569        if self
570            .de
571            .read
572            .get_attribute_value(&self.de.current_field)
573            .is_none()
574        {
575            return Ok(None);
576        }
577        seed.deserialize(&mut *self.de).map(Some)
578    }
579}
580
581struct MapAccess<'a, R: 'a> {
582    de: &'a mut Deserializer<R>,
583    keys: Vec<String>,
584    current: usize,
585}
586
587impl<'a, R: 'a> MapAccess<'a, R> {
588    fn new(de: &'a mut Deserializer<R>, keys: Vec<String>) -> Self {
589        de.as_key = true;
590        MapAccess {
591            de,
592            keys,
593            current: 0,
594        }
595    }
596}
597
598impl<'de, 'a, R: Read + 'a> serde::de::MapAccess<'de> for MapAccess<'a, R> {
599    type Error = Error;
600
601    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
602    where
603        K: serde::de::DeserializeSeed<'de>,
604    {
605        if self.current >= self.keys.len() {
606            Ok(None)
607        } else {
608            self.de.current_field = Index::String(self.keys[self.current].to_string());
609            self.de.as_key = true;
610            self.current += 1;
611            seed.deserialize(&mut *self.de).map(Some)
612        }
613    }
614
615    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
616    where
617        V: serde::de::DeserializeSeed<'de>,
618    {
619        self.de.as_key = false;
620        seed.deserialize(&mut *self.de)
621    }
622}
623
624struct VariantAccess<'a, R: 'a> {
625    de: &'a mut Deserializer<R>,
626}
627
628impl<'a, R: 'a> VariantAccess<'a, R> {
629    fn new(de: &'a mut Deserializer<R>) -> Self {
630        de.as_key = true;
631        VariantAccess { de }
632    }
633}
634
635impl<'de, 'a, R: Read + 'a> serde::de::EnumAccess<'de> for VariantAccess<'a, R> {
636    type Error = Error;
637    type Variant = Self;
638
639    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self)>
640    where
641        V: serde::de::DeserializeSeed<'de>,
642    {
643        let val = seed.deserialize(&mut *self.de)?;
644        Ok((val, self))
645    }
646}
647
648impl<'de, 'a, R: Read + 'a> serde::de::VariantAccess<'de> for VariantAccess<'a, R> {
649    type Error = Error;
650
651    fn unit_variant(self) -> Result<()> {
652        serde::de::Deserialize::deserialize(self.de)
653    }
654
655    fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
656    where
657        T: serde::de::DeserializeSeed<'de>,
658    {
659        seed.deserialize(self.de)
660    }
661
662    fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value>
663    where
664        V: serde::de::Visitor<'de>,
665    {
666        serde::de::Deserializer::deserialize_seq(self.de, visitor)
667    }
668
669    fn struct_variant<V>(self, fields: &'static [&'static str], visitor: V) -> Result<V::Value>
670    where
671        V: serde::de::Visitor<'de>,
672    {
673        serde::de::Deserializer::deserialize_struct(self.de, "", fields, visitor)
674    }
675}
676
677struct UnitVariantAccess<'a, R: 'a> {
678    de: &'a mut Deserializer<R>,
679}
680
681impl<'a, R: 'a> UnitVariantAccess<'a, R> {
682    fn new(de: &'a mut Deserializer<R>) -> Self {
683        de.as_key = true;
684        UnitVariantAccess { de }
685    }
686}
687
688impl<'de, 'a, R: Read + 'a> serde::de::EnumAccess<'de> for UnitVariantAccess<'a, R> {
689    type Error = Error;
690    type Variant = Self;
691
692    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self)>
693    where
694        V: serde::de::DeserializeSeed<'de>,
695    {
696        let variant = seed.deserialize(&mut *self.de)?;
697        Ok((variant, self))
698    }
699}
700
701impl<'de, 'a, R: Read + 'a> serde::de::VariantAccess<'de> for UnitVariantAccess<'a, R> {
702    type Error = Error;
703
704    fn unit_variant(self) -> Result<()> {
705        Ok(())
706    }
707
708    fn newtype_variant_seed<T>(self, _seed: T) -> Result<T::Value>
709    where
710        T: serde::de::DeserializeSeed<'de>,
711    {
712        Err(serde::de::Error::invalid_type(
713            serde::de::Unexpected::UnitVariant,
714            &"newtype variant",
715        ))
716    }
717
718    fn tuple_variant<V>(self, _len: usize, _visitor: V) -> Result<V::Value>
719    where
720        V: serde::de::Visitor<'de>,
721    {
722        Err(serde::de::Error::invalid_type(
723            serde::de::Unexpected::UnitVariant,
724            &"tuple variant",
725        ))
726    }
727
728    fn struct_variant<V>(self, _fields: &'static [&'static str], _visitor: V) -> Result<V::Value>
729    where
730        V: serde::de::Visitor<'de>,
731    {
732        Err(serde::de::Error::invalid_type(
733            serde::de::Unexpected::UnitVariant,
734            &"struct variant",
735        ))
736    }
737}
738
739fn from_trait<'de, R, T>(read: R) -> Result<T>
740where
741    R: Read,
742    T: serde::de::Deserialize<'de>,
743{
744    let mut de = Deserializer::new(read);
745    let value = serde_path_to_error::deserialize(&mut de)?;
746
747    Ok(value)
748}
749
750pub(crate) fn from_hocon<'de, T>(hocon: Hocon) -> Result<T>
751where
752    T: serde::de::Deserialize<'de>,
753{
754    from_trait(HoconRead::new(hocon))
755}
756
757/// Deserialize a HOCON string directly
758pub fn from_str<'de, T>(hocon: &str) -> std::result::Result<T, crate::Error>
759where
760    T: serde::de::Deserialize<'de>,
761{
762    from_trait(HoconRead::new(
763        crate::HoconLoader::new().load_str(hocon)?.hocon()?,
764    ))
765    .map_err(|err| crate::Error::Deserialization {
766        message: err.message,
767    })
768}
769
770#[cfg(test)]
771#[allow(dead_code)]
772mod tests {
773    use crate::Hocon;
774    use linked_hash_map::LinkedHashMap;
775    use serde::Deserialize;
776    use std::collections::HashMap;
777
778    #[derive(Deserialize, Debug)]
779    struct Simple {
780        int: i64,
781        float: f64,
782        option_int: Option<u64>,
783    }
784    #[derive(Deserialize, Debug)]
785    struct WithSubStruct {
786        vec_sub: Vec<Simple>,
787        int: i32,
788        float: f32,
789        boolean: bool,
790        string: String,
791    }
792
793    #[test]
794    fn can_deserialize_struct() {
795        let mut hm = LinkedHashMap::new();
796        hm.insert(String::from("int"), Hocon::Integer(56));
797        hm.insert(String::from("float"), Hocon::Real(543.12));
798        hm.insert(String::from("boolean"), Hocon::Boolean(false));
799        hm.insert(String::from("string"), Hocon::String(String::from("test")));
800        let mut vec_sub = vec![];
801        let mut subhm = LinkedHashMap::new();
802        subhm.insert(String::from("int"), Hocon::Integer(5));
803        subhm.insert(String::from("float"), Hocon::Integer(6));
804        subhm.insert(String::from("extra"), Hocon::Integer(10));
805        let subdoc = Hocon::Hash(subhm);
806        vec_sub.push(subdoc);
807        let mut subhm = LinkedHashMap::new();
808        subhm.insert(String::from("int"), Hocon::Integer(5));
809        subhm.insert(String::from("float"), Hocon::Integer(6));
810        let subdoc = Hocon::Hash(subhm);
811        vec_sub.push(subdoc);
812        let mut subhm = LinkedHashMap::new();
813        subhm.insert(String::from("int"), Hocon::Integer(5));
814        subhm.insert(String::from("float"), Hocon::Integer(6));
815        subhm.insert(String::from("extra"), Hocon::Null);
816        let subdoc = Hocon::Hash(subhm);
817        vec_sub.push(subdoc);
818        hm.insert(String::from("vec_sub"), Hocon::Array(vec_sub));
819        let doc = Hocon::Hash(hm);
820
821        let res: super::Result<WithSubStruct> = dbg!(super::from_hocon(dbg!(doc)));
822        assert!(res.is_ok());
823    }
824
825    #[test]
826    fn will_fail_on_missing_field() {
827        let mut hm = LinkedHashMap::new();
828        hm.insert(String::from("int"), Hocon::Integer(5));
829        let doc = Hocon::Hash(hm);
830
831        let res: super::Result<Simple> = dbg!(super::from_hocon(dbg!(doc)));
832        assert!(res.is_err());
833    }
834
835    #[test]
836    fn will_not_fail_on_extra_field() {
837        let mut hm = LinkedHashMap::new();
838        hm.insert(String::from("int"), Hocon::Integer(5));
839        hm.insert(String::from("float"), Hocon::Integer(6));
840        hm.insert(String::from("extra"), Hocon::Integer(10));
841        let doc = Hocon::Hash(hm);
842
843        let res: super::Result<Simple> = dbg!(super::from_hocon(dbg!(doc)));
844        assert!(res.is_ok());
845    }
846
847    #[test]
848    fn will_fail_on_wrong_type() {
849        let mut hm = LinkedHashMap::new();
850        hm.insert(String::from("int"), Hocon::Integer(5));
851        hm.insert(String::from("float"), Hocon::String(String::from("wrong")));
852        let doc = Hocon::Hash(hm);
853        let res: super::Result<Simple> = dbg!(super::from_hocon(dbg!(doc)));
854        assert!(res.is_err());
855
856        let mut hm = LinkedHashMap::new();
857        hm.insert(String::from("int"), Hocon::Integer(56));
858        hm.insert(String::from("float"), Hocon::Real(543.12));
859        hm.insert(String::from("boolean"), Hocon::Boolean(false));
860        hm.insert(String::from("string"), Hocon::Array(vec![]));
861        hm.insert(String::from("vec_sub"), Hocon::Array(vec![]));
862        let doc = Hocon::Hash(hm);
863        let res: super::Result<WithSubStruct> = dbg!(super::from_hocon(dbg!(doc)));
864        assert!(res.is_err());
865
866        let mut hm = LinkedHashMap::new();
867        hm.insert(String::from("int"), Hocon::Integer(56));
868        hm.insert(String::from("float"), Hocon::Real(543.12));
869        hm.insert(String::from("boolean"), Hocon::Integer(1));
870        hm.insert(String::from("string"), Hocon::String(String::from("test")));
871        hm.insert(String::from("vec_sub"), Hocon::Array(vec![]));
872        let doc = Hocon::Hash(hm);
873        let res: super::Result<WithSubStruct> = dbg!(super::from_hocon(dbg!(doc)));
874        assert!(res.is_err());
875    }
876
877    #[test]
878    fn access_hash_as_array() {
879        #[derive(Deserialize, Debug)]
880        struct WithArray {
881            a: Vec<i32>,
882        }
883
884        let mut array = LinkedHashMap::new();
885        array.insert(String::from("0"), Hocon::Integer(5));
886        array.insert(String::from("2"), Hocon::Integer(7));
887        let mut hm = LinkedHashMap::new();
888        hm.insert(String::from("a"), Hocon::Hash(array));
889        let doc = Hocon::Hash(hm);
890
891        let res: super::Result<WithArray> = dbg!(super::from_hocon(dbg!(doc)));
892        assert!(res.is_ok());
893        assert_eq!(res.expect("during test").a, vec![5, 7]);
894    }
895
896    #[test]
897    fn hoconand_serde_default() {
898        #[derive(Deserialize, Debug)]
899        struct MyStructWithDefaultField {
900            #[serde(default)]
901            size: f64,
902        }
903
904        // let s: MyStruct = HoconLoader::new().load_str("").unwrap().resolve().unwrap();
905        let doc = Hocon::Hash(LinkedHashMap::new());
906
907        let res: super::Result<MyStructWithDefaultField> = dbg!(super::from_hocon(dbg!(doc)));
908        assert!(res.is_ok());
909        assert_eq!(res.expect("during test").size, 0.);
910    }
911
912    #[test]
913    fn unit_struct() {
914        #[derive(Deserialize, Debug, PartialEq)]
915        struct UnitStruct;
916
917        #[derive(Deserialize, Debug)]
918        struct MyStruct {
919            item: UnitStruct,
920        }
921
922        let mut hm = LinkedHashMap::new();
923        hm.insert(String::from("item"), Hocon::Null);
924        let doc = Hocon::Hash(hm);
925
926        let res: super::Result<MyStruct> = dbg!(super::from_hocon(dbg!(doc)));
927        assert!(res.is_ok());
928        assert_eq!(res.expect("during test").item, UnitStruct);
929    }
930
931    #[test]
932    fn tuple() {
933        #[derive(Deserialize, Debug)]
934        struct MyStruct {
935            item: (u64, String),
936        }
937
938        let mut hm = LinkedHashMap::new();
939        let vec_sub = vec![Hocon::Integer(0), Hocon::String(String::from("Hello"))];
940        hm.insert(String::from("item"), Hocon::Array(vec_sub));
941        let doc = Hocon::Hash(hm);
942
943        let res: super::Result<MyStruct> = dbg!(super::from_hocon(dbg!(doc)));
944        assert!(res.is_ok());
945        assert_eq!(res.expect("during test").item, (0, "Hello".to_string()));
946    }
947
948    #[test]
949    fn tuple_struct() {
950        #[derive(Deserialize, Debug, PartialEq)]
951        struct TupleStruct(u64, String);
952
953        #[derive(Deserialize, Debug)]
954        struct MyStruct {
955            item: TupleStruct,
956        }
957
958        let mut hm = LinkedHashMap::new();
959        let vec_sub = vec![Hocon::Integer(0), Hocon::String(String::from("Hello"))];
960        hm.insert(String::from("item"), Hocon::Array(vec_sub));
961        let doc = Hocon::Hash(hm);
962
963        let res: super::Result<MyStruct> = dbg!(super::from_hocon(dbg!(doc)));
964        assert!(res.is_ok());
965        assert_eq!(
966            res.expect("during test").item,
967            TupleStruct(0, "Hello".to_string())
968        );
969    }
970
971    #[test]
972    fn map() {
973        #[derive(Deserialize, Debug)]
974        struct MyStruct {
975            item: HashMap<String, u64>,
976        }
977
978        let mut hm = LinkedHashMap::new();
979        let mut hm_sub = LinkedHashMap::new();
980        hm_sub.insert(String::from("Hello"), Hocon::Integer(7));
981        hm.insert(String::from("item"), Hocon::Hash(hm_sub));
982        let doc = Hocon::Hash(hm);
983
984        let res: super::Result<MyStruct> = dbg!(super::from_hocon(dbg!(doc)));
985        assert!(res.is_ok());
986        assert_eq!(res.expect("during test").item.get("Hello"), Some(&7));
987    }
988
989    #[test]
990    fn map_with_enum_keys() {
991        #[derive(Deserialize, Debug, Hash, PartialEq, Eq)]
992        enum E {
993            A,
994            B,
995        }
996
997        let mut hm = LinkedHashMap::new();
998        hm.insert(String::from("A"), Hocon::Integer(1));
999        hm.insert(String::from("B"), Hocon::Integer(2));
1000        let doc = Hocon::Hash(hm);
1001
1002        let res: super::Result<HashMap<E, u8>> = dbg!(super::from_hocon(dbg!(doc)));
1003        assert!(res.is_ok());
1004        assert_eq!(res.expect("during test").get(&E::A), Some(&1));
1005
1006        #[derive(Deserialize, Debug)]
1007        struct S {
1008            s: u8,
1009        }
1010
1011        let mut hm = LinkedHashMap::new();
1012        let mut hm_sub = LinkedHashMap::new();
1013        hm_sub.insert(String::from("s"), Hocon::Integer(7));
1014        hm.insert(String::from("A"), Hocon::Hash(hm_sub));
1015        let doc = Hocon::Hash(hm);
1016
1017        let res: super::Result<HashMap<E, S>> = dbg!(super::from_hocon(dbg!(doc)));
1018        assert!(res.is_ok());
1019        assert_eq!(res.expect("during test").get(&E::A).unwrap().s, 7);
1020    }
1021
1022    #[derive(Deserialize, Debug, PartialEq)]
1023    #[allow(clippy::enum_variant_names)]
1024    enum MyEnum {
1025        UnitVariant,
1026        TupleVariant(u64, bool),
1027        StructVariant { u: u64, b: bool },
1028    }
1029
1030    #[derive(Deserialize, Debug)]
1031    struct MyStructWithEnum {
1032        item: MyEnum,
1033    }
1034
1035    #[test]
1036    fn deserialize_unit_enum() {
1037        let mut hm = LinkedHashMap::new();
1038        hm.insert(
1039            String::from("item"),
1040            Hocon::String(String::from("UnitVariant")),
1041        );
1042        let doc = Hocon::Hash(hm);
1043
1044        let res: super::Result<MyStructWithEnum> = dbg!(super::from_hocon(dbg!(doc)));
1045        assert!(res.is_ok());
1046        assert_eq!(res.expect("during test").item, MyEnum::UnitVariant);
1047    }
1048
1049    #[test]
1050    fn deserialize_tuple_enum() {
1051        let mut hm = LinkedHashMap::new();
1052        let mut sub_hm = LinkedHashMap::new();
1053        sub_hm.insert(String::from("u"), Hocon::Integer(12));
1054        sub_hm.insert(String::from("b"), Hocon::Boolean(true));
1055        let mut variant_map = LinkedHashMap::new();
1056        variant_map.insert(String::from("StructVariant"), Hocon::Hash(sub_hm));
1057        hm.insert(String::from("item"), Hocon::Hash(variant_map));
1058        let doc = Hocon::Hash(hm);
1059
1060        let res: super::Result<MyStructWithEnum> = dbg!(super::from_hocon(dbg!(doc)));
1061        assert!(res.is_ok());
1062        assert_eq!(
1063            res.expect("during test").item,
1064            MyEnum::StructVariant { u: 12, b: true }
1065        );
1066    }
1067
1068    #[test]
1069    fn deserialize_struct_enum() {
1070        let mut hm = LinkedHashMap::new();
1071        let sub_vec = vec![Hocon::Integer(7), Hocon::Boolean(false)];
1072        let mut variant_map = LinkedHashMap::new();
1073        variant_map.insert(String::from("TupleVariant"), Hocon::Array(sub_vec));
1074        hm.insert(String::from("item"), Hocon::Hash(variant_map));
1075        let doc = Hocon::Hash(hm);
1076
1077        let res: super::Result<MyStructWithEnum> = dbg!(super::from_hocon(dbg!(doc)));
1078        assert!(res.is_ok());
1079        assert_eq!(
1080            res.expect("during test").item,
1081            MyEnum::TupleVariant(7, false)
1082        );
1083    }
1084
1085    #[test]
1086    fn deserialize_tagged_enum() {
1087        #[derive(Debug, Deserialize, PartialEq)]
1088        struct Container {
1089            rp: RetryPolicy,
1090        }
1091        #[derive(Debug, Deserialize, PartialEq)]
1092        #[serde(tag = "type")]
1093        pub enum RetryPolicy {
1094            NoRetry,
1095            Asap { num_retries: u32 },
1096        }
1097
1098        let mut hm = LinkedHashMap::new();
1099        let mut sub_hm = LinkedHashMap::new();
1100        // sub_hm.insert(String::from("type"), Hocon::String(String::from("NoRetry")));
1101        sub_hm.insert(String::from("type"), Hocon::String(String::from("Asap")));
1102        sub_hm.insert(String::from("num_retries"), Hocon::Integer(7));
1103        hm.insert(String::from("rp"), Hocon::Hash(sub_hm));
1104        let doc = Hocon::Hash(hm);
1105
1106        let res: super::Result<Container> = dbg!(super::from_hocon(dbg!(doc)));
1107        assert!(res.is_ok());
1108        assert_eq!(
1109            res.expect("during test").rp,
1110            RetryPolicy::Asap { num_retries: 7 }
1111        );
1112    }
1113}