1use 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!(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 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
757pub 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 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("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}