1mod deconfig;
2mod errors;
3mod level;
4pub use self::errors::*;
5
6use self::deconfig::*;
7use crate::api::ConfigItem;
8use serde::de::{self, Deserialize, DeserializeSeed, MapAccess, SeqAccess, Visitor};
9use serde::forward_to_deserialize_any;
10
11pub type DeResult<T> = Result<T, Error>;
14
15#[derive(Debug, Clone)]
17enum DeType<'a> {
18 Item(&'a str, Vec<DeConfig<'a>>),
20
21 Struct(Vec<(&'a str, Vec<DeConfig<'a>>)>, usize),
23
24 Seq(Vec<DeConfig<'a>>, usize),
26}
27
28pub struct Deserializer<'a> {
29 depth: Vec<DeType<'a>>,
30}
31
32impl<'a> Deserializer<'a> {
33 fn from_collectd(input: Vec<(&'a str, Vec<DeConfig<'a>>)>) -> Self {
34 Deserializer {
35 depth: vec![DeType::Struct(input, 0)],
36 }
37 }
38
39 fn current(&self) -> DeResult<&DeType<'a>> {
40 if self.depth.is_empty() {
41 return Err(Error(DeError::NoMoreValuesLeft));
42 }
43
44 Ok(&self.depth[self.depth.len() - 1])
45 }
46
47 fn grab_val(&self) -> DeResult<&DeConfig<'a>> {
48 match *self.current()? {
49 DeType::Item(_, ref values) => {
50 if values.len() != 1 {
51 return Err(Error(DeError::ExpectSingleValue));
52 }
53
54 Ok(&values[0])
55 }
56 DeType::Seq(ref items, ind) => Ok(&items[ind]),
57 _ => Err(Error(DeError::ExpectSingleValue)),
58 }
59 }
60
61 fn grab_string(&self) -> DeResult<&'a str> {
62 if let DeConfig::String(x) = *self.grab_val()? {
63 Ok(x)
64 } else {
65 Err(Error(DeError::ExpectString))
66 }
67 }
68
69 fn grab_bool(&self) -> DeResult<bool> {
70 if let DeConfig::Boolean(x) = *self.grab_val()? {
71 Ok(x)
72 } else {
73 Err(Error(DeError::ExpectBoolean))
74 }
75 }
76
77 fn grab_number(&self) -> DeResult<f64> {
78 if let DeConfig::Number(x) = *self.grab_val()? {
79 Ok(x)
80 } else {
81 Err(Error(DeError::ExpectNumber))
82 }
83 }
84
85 fn pop(&mut self) {
86 self.depth.pop();
87 }
88
89 fn push(&mut self, pos: usize) {
90 let cur = if pos == 0 { 1 } else { 2 };
92 let end = self.depth.len() - cur;
93
94 let mut t = None;
95 if let DeType::Struct(ref values, _ind) = self.depth[end] {
96 t = Some(values[pos].clone());
97 }
98
99 if let Some((key, vs)) = t {
100 if pos == 0 {
101 self.depth.push(DeType::Item(key, vs));
102 } else {
103 let end = self.depth.len() - 1;
104 self.depth[end] = DeType::Item(key, vs);
105 }
106 }
107 }
108
109 fn push_seq(&mut self, pos: usize) {
110 let cur = if pos == 0 { 1 } else { 2 };
112 let end = self.depth.len() - cur;
113
114 let mut t = None;
115 if let DeType::Item(_key, ref values) = self.depth[end] {
116 t = Some(values.clone());
117 }
118
119 if let Some(vs) = t {
120 if pos == 0 {
121 self.depth.push(DeType::Seq(vs, pos));
122 } else {
123 let end = self.depth.len() - 1;
124 self.depth[end] = DeType::Seq(vs, pos);
125 }
126 }
127 }
128}
129
130pub fn from_collectd<'a, T>(s: &'a [ConfigItem<'a>]) -> DeResult<T>
131where
132 T: Deserialize<'a>,
133{
134 let props = from_config(s);
135 let mut deserializer = Deserializer::from_collectd(props);
136 T::deserialize(&mut deserializer)
137}
138
139impl<'de> de::Deserializer<'de> for &mut Deserializer<'de> {
140 type Error = Error;
141
142 fn deserialize_bool<V>(self, visitor: V) -> DeResult<V::Value>
143 where
144 V: Visitor<'de>,
145 {
146 self.grab_bool().and_then(|x| visitor.visit_bool(x))
147 }
148
149 fn deserialize_string<V>(self, visitor: V) -> DeResult<V::Value>
150 where
151 V: Visitor<'de>,
152 {
153 self.grab_string()
154 .and_then(|x| visitor.visit_string(String::from(x)))
155 }
156
157 fn deserialize_str<V>(self, visitor: V) -> DeResult<V::Value>
158 where
159 V: Visitor<'de>,
160 {
161 self.grab_string()
162 .and_then(|x| visitor.visit_borrowed_str(x))
163 }
164
165 fn deserialize_i8<V>(self, visitor: V) -> DeResult<V::Value>
166 where
167 V: Visitor<'de>,
168 {
169 self.grab_number().and_then(|x| visitor.visit_i8(x as i8))
170 }
171
172 fn deserialize_i16<V>(self, visitor: V) -> DeResult<V::Value>
173 where
174 V: Visitor<'de>,
175 {
176 self.grab_number().and_then(|x| visitor.visit_i16(x as i16))
177 }
178
179 fn deserialize_i32<V>(self, visitor: V) -> DeResult<V::Value>
180 where
181 V: Visitor<'de>,
182 {
183 self.grab_number().and_then(|x| visitor.visit_i32(x as i32))
184 }
185
186 fn deserialize_i64<V>(self, visitor: V) -> DeResult<V::Value>
187 where
188 V: Visitor<'de>,
189 {
190 self.grab_number().and_then(|x| visitor.visit_i64(x as i64))
191 }
192
193 fn deserialize_u8<V>(self, visitor: V) -> DeResult<V::Value>
194 where
195 V: Visitor<'de>,
196 {
197 self.grab_number().and_then(|x| visitor.visit_u8(x as u8))
198 }
199
200 fn deserialize_u16<V>(self, visitor: V) -> DeResult<V::Value>
201 where
202 V: Visitor<'de>,
203 {
204 self.grab_number().and_then(|x| visitor.visit_u16(x as u16))
205 }
206
207 fn deserialize_u32<V>(self, visitor: V) -> DeResult<V::Value>
208 where
209 V: Visitor<'de>,
210 {
211 self.grab_number().and_then(|x| visitor.visit_u32(x as u32))
212 }
213
214 fn deserialize_u64<V>(self, visitor: V) -> DeResult<V::Value>
215 where
216 V: Visitor<'de>,
217 {
218 self.grab_number().and_then(|x| visitor.visit_u64(x as u64))
219 }
220
221 fn deserialize_f32<V>(self, visitor: V) -> DeResult<V::Value>
222 where
223 V: Visitor<'de>,
224 {
225 self.grab_number().and_then(|x| visitor.visit_f32(x as f32))
226 }
227
228 fn deserialize_f64<V>(self, visitor: V) -> DeResult<V::Value>
229 where
230 V: Visitor<'de>,
231 {
232 self.grab_number().and_then(|x| visitor.visit_f64(x))
233 }
234
235 fn deserialize_option<V>(self, visitor: V) -> DeResult<V::Value>
236 where
237 V: Visitor<'de>,
238 {
239 visitor.visit_some(self)
240 }
241
242 fn deserialize_char<V>(self, visitor: V) -> DeResult<V::Value>
243 where
244 V: Visitor<'de>,
245 {
246 self.grab_string().and_then(|x| {
247 if x.len() != 1 {
248 Err(Error(DeError::ExpectChar(String::from(x))))
249 } else {
250 visitor.visit_char(x.chars().next().unwrap())
251 }
252 })
253 }
254
255 fn deserialize_identifier<V>(self, visitor: V) -> DeResult<V::Value>
256 where
257 V: Visitor<'de>,
258 {
259 let v = &self.depth[self.depth.len() - 1];
260 match *v {
261 DeType::Item(key, _) => visitor.visit_borrowed_str(key),
262 DeType::Seq(ref x, pos) if pos == 0 => {
263 if let DeConfig::String(ss) = x[pos] {
264 visitor.visit_borrowed_str(ss)
265 } else {
266 Err(de::Error::custom("expected the first element, when deserializing for an identifier, to be a string"))
267 }
268 }
269 _ => Err(de::Error::custom(
270 "expected an item when deserializing identifier",
271 )),
272 }
273 }
274
275 fn deserialize_seq<V>(self, visitor: V) -> DeResult<V::Value>
276 where
277 V: Visitor<'de>,
278 {
279 let len = if let DeType::Item(_key, ref v) = *self.current()? {
280 v.len()
281 } else {
282 return Err(de::Error::custom("expected an item when deserializing seq"));
283 };
284
285 visitor.visit_seq(SeqSeparated::new(self, len))
286 }
287
288 fn deserialize_struct<V>(
289 self,
290 _name: &'static str,
291 _fields: &'static [&'static str],
292 visitor: V,
293 ) -> DeResult<V::Value>
294 where
295 V: Visitor<'de>,
296 {
297 let mut to_pop = false;
300
301 let t = match self.current()?.clone() {
302 DeType::Struct(ref values, _ind) => Some(values.len()),
303 DeType::Seq(ref values, ind) => {
304 if let DeConfig::Object(ref obj) = values[ind] {
305 let s = DeType::Struct(obj.clone(), 0);
307 self.depth.push(s);
308 to_pop = true;
309 Some(obj.len())
310 } else {
311 return Err(Error(DeError::ExpectObject));
312 }
313 }
314 _ => None,
315 };
316
317 let res = visitor.visit_map(FieldSeparated::new(self, t.unwrap_or(0)))?;
318 if to_pop {
319 self.pop();
320 }
321 Ok(res)
322 }
323
324 fn deserialize_ignored_any<V>(self, visitor: V) -> DeResult<V::Value>
325 where
326 V: Visitor<'de>,
327 {
328 visitor.visit_none()
329 }
330
331 fn deserialize_any<V>(self, _visitor: V) -> DeResult<V::Value>
332 where
333 V: Visitor<'de>,
334 {
335 Err(Error(DeError::DataTypeNotSupported))
336 }
337
338 fn deserialize_newtype_struct<V>(self, _name: &str, visitor: V) -> DeResult<V::Value>
339 where
340 V: Visitor<'de>,
341 {
342 visitor.visit_newtype_struct(self)
343 }
344
345 fn deserialize_enum<V>(
346 self,
347 _name: &str,
348 _variants: &'static [&'static str],
349 visitor: V,
350 ) -> DeResult<V::Value>
351 where
352 V: Visitor<'de>,
353 {
354 if let DeType::Item(_key, ref v) = self.current()?.clone() {
355 if v.len() != 1 {
356 return Err(de::Error::custom(
357 "expected enum item to have a single item list",
358 ));
359 }
360
361 self.push_seq(0);
366 let res = visitor.visit_enum(UnitVariantAccess::new(self))?;
367 self.pop();
368 Ok(res)
369 } else {
370 Err(Error(DeError::ExpectStruct))
371 }
372 }
373
374 forward_to_deserialize_any! {
375 bytes
376 byte_buf unit unit_struct tuple
377 tuple_struct map
378 }
379}
380
381struct UnitVariantAccess<'a, 'de: 'a> {
382 de: &'a mut Deserializer<'de>,
383}
384
385impl<'a, 'de: 'a> UnitVariantAccess<'a, 'de> {
386 fn new(de: &'a mut Deserializer<'de>) -> Self {
387 UnitVariantAccess { de }
388 }
389}
390
391impl<'de> de::EnumAccess<'de> for UnitVariantAccess<'_, 'de> {
392 type Error = Error;
393 type Variant = Self;
394
395 fn variant_seed<V>(self, seed: V) -> DeResult<(V::Value, Self)>
396 where
397 V: de::DeserializeSeed<'de>,
398 {
399 let variant = seed.deserialize(&mut *self.de)?;
400 Ok((variant, self))
401 }
402}
403
404impl<'de> de::VariantAccess<'de> for UnitVariantAccess<'_, 'de> {
405 type Error = Error;
406
407 fn unit_variant(self) -> DeResult<()> {
408 Ok(())
409 }
410
411 fn newtype_variant_seed<T>(self, _seed: T) -> DeResult<T::Value>
412 where
413 T: de::DeserializeSeed<'de>,
414 {
415 Err(de::Error::custom("newtype variant"))
416 }
417
418 fn tuple_variant<V>(self, _len: usize, _visitor: V) -> DeResult<V::Value>
419 where
420 V: de::Visitor<'de>,
421 {
422 Err(de::Error::custom("tuple variant"))
423 }
424
425 fn struct_variant<V>(self, _fields: &'static [&'static str], _visitor: V) -> DeResult<V::Value>
426 where
427 V: de::Visitor<'de>,
428 {
429 Err(de::Error::custom("struct variant"))
430 }
431}
432
433struct FieldSeparated<'a, 'de: 'a> {
434 de: &'a mut Deserializer<'de>,
435 item_count: usize,
436 item_pos: usize,
437}
438
439impl<'a, 'de> FieldSeparated<'a, 'de> {
440 fn new(de: &'a mut Deserializer<'de>, item_count: usize) -> Self {
441 FieldSeparated {
442 de,
443 item_pos: 0,
444 item_count,
445 }
446 }
447}
448
449impl<'de> MapAccess<'de> for FieldSeparated<'_, 'de> {
450 type Error = Error;
451
452 fn next_key_seed<K>(&mut self, seed: K) -> DeResult<Option<K::Value>>
453 where
454 K: DeserializeSeed<'de>,
455 {
456 if self.item_pos == self.item_count {
458 if self.item_count != 0 {
459 self.de.pop();
460 }
461 return Ok(None);
462 }
463
464 self.de.push(self.item_pos);
465 self.item_pos += 1;
466 seed.deserialize(&mut *self.de).map(Some)
467 }
468
469 fn next_value_seed<V>(&mut self, seed: V) -> DeResult<V::Value>
470 where
471 V: DeserializeSeed<'de>,
472 {
473 seed.deserialize(&mut *self.de)
474 }
475}
476
477struct SeqSeparated<'a, 'de: 'a> {
478 de: &'a mut Deserializer<'de>,
479 item_count: usize,
480 item_pos: usize,
481}
482
483impl<'a, 'de> SeqSeparated<'a, 'de> {
484 fn new(de: &'a mut Deserializer<'de>, item_count: usize) -> Self {
485 SeqSeparated {
486 de,
487 item_count,
488 item_pos: 0,
489 }
490 }
491}
492
493impl<'de> SeqAccess<'de> for SeqSeparated<'_, 'de> {
494 type Error = Error;
495
496 fn next_element_seed<T>(&mut self, seed: T) -> DeResult<Option<T::Value>>
497 where
498 T: DeserializeSeed<'de>,
499 {
500 if self.item_pos == self.item_count {
501 if self.item_count != 0 {
502 self.de.pop();
503 }
504 return Ok(None);
505 }
506
507 self.de.push_seq(self.item_pos);
508 self.item_pos += 1;
509 seed.deserialize(&mut *self.de).map(Some)
510 }
511}
512
513#[cfg(test)]
514mod tests {
515 use super::super::ConfigValue;
516 use super::*;
517 use crate::api::LogLevel;
518 use serde::Deserialize;
519
520 #[test]
521 fn test_serde_simple_bool() {
522 #[derive(Deserialize, PartialEq, Eq, Debug)]
523 struct MyStruct {
524 my_bool: bool,
525 }
526
527 let items = vec![ConfigItem {
528 key: "my_bool",
529 values: vec![ConfigValue::Boolean(true)],
530 children: vec![],
531 }];
532
533 let actual = from_collectd(&items).unwrap();
534 assert_eq!(MyStruct { my_bool: true }, actual);
535 }
536
537 #[test]
538 fn test_serde_empty_bool() {
539 #[derive(Deserialize, PartialEq, Eq, Debug)]
540 struct MyStruct {
541 my_bool: Option<bool>,
542 }
543
544 let actual = from_collectd(Default::default()).unwrap();
545 assert_eq!(MyStruct { my_bool: None }, actual);
546 }
547
548 #[test]
549 fn test_serde_simple_number() {
550 #[derive(Deserialize, PartialEq, Eq, Debug)]
551 struct MyStruct {
552 my_int: i8,
553 }
554
555 let items = vec![ConfigItem {
556 key: "my_int",
557 values: vec![ConfigValue::Number(1.0)],
558 children: vec![],
559 }];
560
561 let actual = from_collectd(&items).unwrap();
562 assert_eq!(MyStruct { my_int: 1 }, actual);
563 }
564
565 #[test]
566 fn test_serde_simple_string() {
567 #[derive(Deserialize, PartialEq, Eq, Debug)]
568 struct MyStruct {
569 my_string: String,
570 }
571
572 let items = vec![ConfigItem {
573 key: "my_string",
574 values: vec![ConfigValue::String("HEY")],
575 children: vec![],
576 }];
577
578 let actual = from_collectd(&items).unwrap();
579 assert_eq!(
580 MyStruct {
581 my_string: String::from("HEY"),
582 },
583 actual
584 );
585 }
586
587 #[test]
588 fn test_serde_simple_str() {
589 #[derive(Deserialize, PartialEq, Eq, Debug)]
590 struct MyStruct<'a> {
591 my_string: &'a str,
592 }
593
594 let items = vec![ConfigItem {
595 key: "my_string",
596 values: vec![ConfigValue::String("HEY")],
597 children: vec![],
598 }];
599
600 let actual = from_collectd(&items).unwrap();
601 assert_eq!(MyStruct { my_string: "HEY" }, actual);
602 }
603
604 #[test]
605 fn test_serde_multiple() {
606 #[derive(Deserialize, PartialEq, Eq, Debug)]
607 struct MyStruct {
608 my_bool: bool,
609 my_string: String,
610 }
611
612 let items = vec![
613 ConfigItem {
614 key: "my_bool",
615 values: vec![ConfigValue::Boolean(true)],
616 children: vec![],
617 },
618 ConfigItem {
619 key: "my_string",
620 values: vec![ConfigValue::String("/")],
621 children: vec![],
622 },
623 ];
624
625 let actual = from_collectd(&items).unwrap();
626 assert_eq!(
627 MyStruct {
628 my_bool: true,
629 my_string: String::from("/"),
630 },
631 actual
632 );
633 }
634
635 #[test]
636 fn test_serde_bool_vec() {
637 #[derive(Deserialize, PartialEq, Eq, Debug)]
638 struct MyStruct {
639 my_bool: Vec<bool>,
640 }
641
642 let items = vec![ConfigItem {
643 key: "my_bool",
644 values: vec![ConfigValue::Boolean(true), ConfigValue::Boolean(false)],
645 children: vec![],
646 }];
647
648 let actual = from_collectd(&items).unwrap();
649 assert_eq!(
650 MyStruct {
651 my_bool: vec![true, false],
652 },
653 actual
654 );
655 }
656
657 #[test]
658 fn test_serde_bool_vec_sep() {
659 #[derive(Deserialize, PartialEq, Eq, Debug)]
660 struct MyStruct {
661 my_bool: Vec<bool>,
662 }
663
664 let items = vec![
665 ConfigItem {
666 key: "my_bool",
667 values: vec![ConfigValue::Boolean(true)],
668 children: vec![],
669 },
670 ConfigItem {
671 key: "my_bool",
672 values: vec![ConfigValue::Boolean(false)],
673 children: vec![],
674 },
675 ];
676
677 let actual = from_collectd(&items).unwrap();
678 assert_eq!(
679 MyStruct {
680 my_bool: vec![true, false],
681 },
682 actual
683 );
684 }
685
686 #[test]
687 fn test_serde_multiple_vec() {
688 #[derive(Deserialize, PartialEq, Debug)]
689 struct MyStruct {
690 my_bool: Vec<bool>,
691 my_num: Vec<f64>,
692 }
693
694 let items = vec![
695 ConfigItem {
696 key: "my_bool",
697 values: vec![ConfigValue::Boolean(true)],
698 children: vec![],
699 },
700 ConfigItem {
701 key: "my_bool",
702 values: vec![ConfigValue::Boolean(false)],
703 children: vec![],
704 },
705 ConfigItem {
706 key: "my_num",
707 values: vec![ConfigValue::Number(10.0), ConfigValue::Number(12.0)],
708 children: vec![],
709 },
710 ];
711
712 let actual = from_collectd(&items).unwrap();
713 assert_eq!(
714 MyStruct {
715 my_bool: vec![true, false],
716 my_num: vec![10.0, 12.0],
717 },
718 actual
719 );
720 }
721
722 #[test]
723 fn test_serde_options() {
724 #[derive(Deserialize, PartialEq, Eq, Debug)]
725 struct MyStruct {
726 my_bool: Option<bool>,
727 my_string: Option<String>,
728 }
729
730 let items = vec![ConfigItem {
731 key: "my_bool",
732 values: vec![ConfigValue::Boolean(true)],
733 children: vec![],
734 }];
735
736 let actual = from_collectd(&items).unwrap();
737 assert_eq!(
738 MyStruct {
739 my_bool: Some(true),
740 my_string: None,
741 },
742 actual
743 );
744 }
745
746 #[test]
747 fn test_serde_log_level() {
748 #[derive(Deserialize, PartialEq, Eq, Debug)]
749 struct MyStruct {
750 warn: LogLevel,
751 warning: LogLevel,
752 err: LogLevel,
753 error: LogLevel,
754 debug: LogLevel,
755 info: LogLevel,
756 notice: LogLevel,
757 }
758
759 let items = vec![
760 ConfigItem {
761 key: "warn",
762 values: vec![ConfigValue::String("warn")],
763 children: vec![],
764 },
765 ConfigItem {
766 key: "warning",
767 values: vec![ConfigValue::String("Warning")],
768 children: vec![],
769 },
770 ConfigItem {
771 key: "err",
772 values: vec![ConfigValue::String("ErR")],
773 children: vec![],
774 },
775 ConfigItem {
776 key: "error",
777 values: vec![ConfigValue::String("Error")],
778 children: vec![],
779 },
780 ConfigItem {
781 key: "debug",
782 values: vec![ConfigValue::String("debug")],
783 children: vec![],
784 },
785 ConfigItem {
786 key: "info",
787 values: vec![ConfigValue::String("INFO")],
788 children: vec![],
789 },
790 ConfigItem {
791 key: "notice",
792 values: vec![ConfigValue::String("notice")],
793 children: vec![],
794 },
795 ];
796
797 let actual = from_collectd(&items).unwrap();
798 assert_eq!(
799 MyStruct {
800 warn: LogLevel::Warning,
801 warning: LogLevel::Warning,
802 err: LogLevel::Error,
803 error: LogLevel::Error,
804 debug: LogLevel::Debug,
805 info: LogLevel::Info,
806 notice: LogLevel::Notice,
807 },
808 actual
809 );
810 }
811
812 #[test]
813 fn test_serde_char() {
814 #[derive(Deserialize, PartialEq, Eq, Debug)]
815 struct MyStruct {
816 my_char: char,
817 }
818
819 let items = vec![ConfigItem {
820 key: "my_char",
821 values: vec![ConfigValue::String("/")],
822 children: vec![],
823 }];
824
825 let actual = from_collectd(&items).unwrap();
826 assert_eq!(MyStruct { my_char: '/' }, actual);
827 }
828
829 #[test]
830 fn test_serde_ignore() {
831 #[derive(Deserialize, PartialEq, Eq, Debug)]
832 struct MyStruct {
833 my_char: char,
834 }
835
836 let items = vec![
837 ConfigItem {
838 key: "my_char",
839 values: vec![ConfigValue::String("/")],
840 children: vec![],
841 },
842 ConfigItem {
843 key: "my_boat",
844 values: vec![ConfigValue::String("/")],
845 children: vec![],
846 },
847 ];
848
849 let actual = from_collectd(&items).unwrap();
850 assert_eq!(MyStruct { my_char: '/' }, actual);
851 }
852
853 #[test]
854 fn test_serde_nested() {
855 #[derive(Deserialize, PartialEq, Eq, Debug)]
856 struct MyPort {
857 port: i32,
858 }
859
860 #[derive(Deserialize, PartialEq, Eq, Debug)]
861 struct MyStruct {
862 ports: Vec<MyPort>,
863 }
864
865 let items = vec![
866 ConfigItem {
867 key: "ports",
868 values: vec![],
869 children: vec![ConfigItem {
870 key: "port",
871 values: vec![ConfigValue::Number(2003.0)],
872 children: vec![],
873 }],
874 },
875 ConfigItem {
876 key: "ports",
877 values: vec![],
878 children: vec![ConfigItem {
879 key: "port",
880 values: vec![ConfigValue::Number(2004.0)],
881 children: vec![],
882 }],
883 },
884 ];
885
886 let actual = from_collectd(&items).unwrap();
887 assert_eq!(
888 MyStruct {
889 ports: vec![MyPort { port: 2003 }, MyPort { port: 2004 }],
890 },
891 actual
892 );
893 }
894
895 #[test]
896 fn test_serde_nested_multiple() {
897 #[derive(Deserialize, PartialEq, Eq, Debug)]
898 struct MyAddress {
899 port: i32,
900 host: String,
901 }
902
903 #[derive(Deserialize, PartialEq, Eq, Debug)]
904 struct MyStruct {
905 address: Vec<MyAddress>,
906 }
907
908 let items = vec![
909 ConfigItem {
910 key: "address",
911 values: vec![],
912 children: vec![
913 ConfigItem {
914 key: "port",
915 values: vec![ConfigValue::Number(2003.0)],
916 children: vec![],
917 },
918 ConfigItem {
919 key: "host",
920 values: vec![ConfigValue::String("localhost")],
921 children: vec![],
922 },
923 ],
924 },
925 ConfigItem {
926 key: "address",
927 values: vec![],
928 children: vec![
929 ConfigItem {
930 key: "host",
931 values: vec![ConfigValue::String("127.0.0.1")],
932 children: vec![],
933 },
934 ConfigItem {
935 key: "port",
936 values: vec![ConfigValue::Number(2004.0)],
937 children: vec![],
938 },
939 ],
940 },
941 ];
942
943 let actual = from_collectd(&items).unwrap();
944 assert_eq!(
945 MyStruct {
946 address: vec![
947 MyAddress {
948 host: String::from("localhost"),
949 port: 2003,
950 },
951 MyAddress {
952 host: String::from("127.0.0.1"),
953 port: 2004,
954 },
955 ],
956 },
957 actual
958 );
959 }
960
961 #[test]
962 fn test_serde_new_type() {
963 #[derive(Deserialize, PartialEq, Eq, Debug)]
964 struct MyNew(String);
965
966 #[derive(Deserialize, PartialEq, Eq, Debug)]
967 struct MyStruct {
968 it: MyNew,
969 }
970
971 let items = vec![ConfigItem {
972 key: "it",
973 values: vec![ConfigValue::String("INFO")],
974 children: vec![],
975 }];
976
977 let actual = from_collectd(&items).unwrap();
978 assert_eq!(
979 MyStruct {
980 it: MyNew(String::from("INFO"))
981 },
982 actual
983 );
984 }
985
986 #[test]
987 fn test_log_serde_enum() {
988 use log::Level;
989
990 #[derive(Deserialize, PartialEq, Eq, Debug)]
991 #[serde(deny_unknown_fields)]
992 struct MyStruct {
993 it: Level,
994 sentinel: i32,
995 }
996
997 let items = vec![
998 ConfigItem {
999 key: "it",
1000 values: vec![ConfigValue::String("INFO")],
1001 children: vec![],
1002 },
1003 ConfigItem {
1004 key: "sentinel",
1005 values: vec![ConfigValue::Number(2003.0)],
1006 children: vec![],
1007 },
1008 ];
1009
1010 let actual = from_collectd(&items).unwrap();
1011 assert_eq!(
1012 MyStruct {
1013 it: Level::Info,
1014 sentinel: 2003
1015 },
1016 actual
1017 );
1018 }
1019
1020 #[test]
1021 fn test_serde_enum() {
1022 #[derive(PartialEq, Eq, Debug)]
1023 enum MyEnum {
1024 Foo,
1025 }
1026
1027 use serde::de::{self, Deserializer};
1028
1029 impl<'de> Deserialize<'de> for MyEnum {
1030 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1031 where
1032 D: Deserializer<'de>,
1033 {
1034 let s = String::deserialize(deserializer)?;
1035 match s.as_str() {
1036 "Foo" => Ok(MyEnum::Foo),
1037 _ => Err(de::Error::custom(format!("bad type: {}", s))),
1038 }
1039 }
1040 }
1041
1042 #[derive(Deserialize, PartialEq, Eq, Debug)]
1043 #[serde(deny_unknown_fields)]
1044 struct MyStruct {
1045 it: MyEnum,
1046 sentinel: i32,
1047 }
1048
1049 let items = vec![
1050 ConfigItem {
1051 key: "it",
1052 values: vec![ConfigValue::String("Foo")],
1053 children: vec![],
1054 },
1055 ConfigItem {
1056 key: "sentinel",
1057 values: vec![ConfigValue::Number(2003.0)],
1058 children: vec![],
1059 },
1060 ];
1061
1062 let actual = from_collectd(&items).unwrap();
1063 assert_eq!(
1064 MyStruct {
1065 it: MyEnum::Foo,
1066 sentinel: 2003
1067 },
1068 actual
1069 );
1070 }
1071}