1#![deny(
318 unsafe_code,
319 missing_docs,
320 missing_copy_implementations,
321 missing_debug_implementations
322)]
323
324#[cfg(feature = "raw-node")]
325mod raw_node;
326
327use std::char::ParseCharError;
328use std::error::Error as StdError;
329use std::fmt;
330use std::iter::{once, Peekable};
331use std::marker::PhantomData;
332use std::num::{ParseFloatError, ParseIntError};
333use std::str::{FromStr, ParseBoolError};
334
335use bit_set::BitSet;
336use roxmltree::{Attribute, Document, Error as XmlError, Node};
337use serde_core::de;
338
339pub use roxmltree;
340
341#[cfg(feature = "raw-node")]
342pub use raw_node::RawNode;
343
344pub fn from_str<T>(text: &str) -> Result<T, Error>
346where
347 T: de::DeserializeOwned,
348{
349 defaults().from_str(text)
350}
351
352pub fn from_doc<'de, 'input, T>(document: &'de Document<'input>) -> Result<T, Error>
354where
355 T: de::Deserialize<'de>,
356{
357 defaults().from_doc(document)
358}
359
360pub fn from_node<'de, 'input, T>(node: Node<'de, 'input>) -> Result<T, Error>
362where
363 T: de::Deserialize<'de>,
364{
365 defaults().from_node(node)
366}
367
368pub trait Options: Sized {
373 #[allow(clippy::wrong_self_convention)]
375 fn from_str<T>(self, text: &str) -> Result<T, Error>
376 where
377 T: de::DeserializeOwned,
378 {
379 let document = Document::parse(text).map_err(Error::ParseXml)?;
380 self.from_doc(&document)
381 }
382
383 #[allow(clippy::wrong_self_convention)]
385 fn from_doc<'de, 'input, T>(self, document: &'de Document<'input>) -> Result<T, Error>
386 where
387 T: de::Deserialize<'de>,
388 {
389 let node = document.root_element();
390 self.from_node(node)
391 }
392
393 #[allow(clippy::wrong_self_convention)]
395 fn from_node<'de, 'input, T>(self, node: Node<'de, 'input>) -> Result<T, Error>
396 where
397 T: de::Deserialize<'de>,
398 {
399 let deserializer = Deserializer {
400 source: Source::Node(node),
401 temp: &mut Temp::default(),
402 options: PhantomData::<Self>,
403 };
404 T::deserialize(deserializer)
405 }
406
407 fn namespaces(self) -> Namespaces<Self> {
412 Namespaces(PhantomData)
413 }
414
415 fn prefix_attr(self) -> PrefixAttr<Self> {
420 PrefixAttr(PhantomData)
421 }
422
423 fn only_children(self) -> OnlyChildren<Self> {
428 OnlyChildren(PhantomData)
429 }
430
431 #[doc(hidden)]
432 const NAMESPACES: bool = false;
433
434 #[doc(hidden)]
435 const PREFIX_ATTR: bool = false;
436
437 #[doc(hidden)]
438 const ONLY_CHILDREN: bool = false;
439}
440
441#[doc(hidden)]
442#[derive(Clone, Copy, Default, Debug)]
443pub struct Defaults;
444
445pub fn defaults() -> Defaults {
447 Defaults
448}
449
450impl Options for Defaults {}
451
452#[doc(hidden)]
453#[derive(Clone, Copy, Default, Debug)]
454pub struct Namespaces<O>(PhantomData<O>);
455
456impl<O> Options for Namespaces<O>
457where
458 O: Options,
459{
460 const NAMESPACES: bool = true;
461 const PREFIX_ATTR: bool = O::PREFIX_ATTR;
462 const ONLY_CHILDREN: bool = O::ONLY_CHILDREN;
463}
464
465#[doc(hidden)]
466#[derive(Clone, Copy, Default, Debug)]
467pub struct PrefixAttr<O>(PhantomData<O>);
468
469impl<O> Options for PrefixAttr<O>
470where
471 O: Options,
472{
473 const NAMESPACES: bool = O::NAMESPACES;
474 const PREFIX_ATTR: bool = true;
475 const ONLY_CHILDREN: bool = O::ONLY_CHILDREN;
476}
477
478#[doc(hidden)]
479#[derive(Clone, Copy, Default, Debug)]
480pub struct OnlyChildren<O>(PhantomData<O>);
481
482impl<O> Options for OnlyChildren<O>
483where
484 O: Options,
485{
486 const NAMESPACES: bool = O::NAMESPACES;
487 const PREFIX_ATTR: bool = O::PREFIX_ATTR;
488 const ONLY_CHILDREN: bool = true;
489}
490
491struct Deserializer<'de, 'input, 'temp, O> {
492 source: Source<'de, 'input>,
493 temp: &'temp mut Temp,
494 options: PhantomData<O>,
495}
496
497#[derive(Clone, Copy)]
498enum Source<'de, 'input> {
499 Node(Node<'de, 'input>),
500 Attribute(Attribute<'de, 'input>),
501 Content(Node<'de, 'input>),
502 Missing,
503}
504
505impl Source<'_, '_> {
506 fn name<'a, O>(&'a self, buffer: &'a mut String) -> &'a str
507 where
508 O: Options,
509 {
510 match self {
511 Self::Node(node) => {
512 let tag_name = node.tag_name();
513 let name = tag_name.name();
514
515 match tag_name.namespace() {
516 Some(namespace) if O::NAMESPACES => {
517 buffer.clear();
518
519 buffer.reserve(namespace.len() + 2 + name.len());
520
521 buffer.push('{');
522 buffer.push_str(namespace);
523 buffer.push('}');
524
525 buffer.push_str(name);
526
527 &*buffer
528 }
529 _ => name,
530 }
531 }
532 Self::Attribute(attr) => {
533 let name = attr.name();
534
535 match attr.namespace() {
536 Some(namespace) if O::NAMESPACES => {
537 buffer.clear();
538
539 if O::PREFIX_ATTR {
540 buffer.reserve(3 + namespace.len() + name.len());
541
542 buffer.push('@');
543 } else {
544 buffer.reserve(2 + namespace.len() + name.len());
545 }
546
547 buffer.push('{');
548 buffer.push_str(namespace);
549 buffer.push('}');
550
551 buffer.push_str(name);
552
553 &*buffer
554 }
555 _ => {
556 if O::PREFIX_ATTR {
557 buffer.clear();
558
559 buffer.reserve(1 + name.len());
560
561 buffer.push('@');
562 buffer.push_str(name);
563
564 &*buffer
565 } else {
566 name
567 }
568 }
569 }
570 }
571 Self::Content(_) => "#content",
572 Self::Missing => "#missing",
573 }
574 }
575}
576
577#[derive(Default)]
578struct Temp {
579 visited: BitSet<usize>,
580 buffer: String,
581}
582
583impl<'de, 'input, O> Deserializer<'de, 'input, '_, O>
584where
585 O: Options,
586{
587 fn name(&mut self) -> &str {
588 self.source.name::<O>(&mut self.temp.buffer)
589 }
590
591 fn node(&self) -> Result<&Node<'de, 'input>, Error> {
592 match &self.source {
593 Source::Node(node) | Source::Content(node) => Ok(node),
594 Source::Attribute(_) | Source::Missing => Err(Error::MissingNode),
595 }
596 }
597
598 fn children(&self) -> Result<impl Iterator<Item = Source<'de, 'input>>, Error> {
599 let node = self.node()?;
600
601 let children = node
602 .children()
603 .filter(|node| node.is_element())
604 .map(Source::Node);
605
606 Ok(children)
607 }
608
609 fn children_and_attributes(&self) -> Result<impl Iterator<Item = Source<'de, 'input>>, Error> {
610 let node = self.node()?;
611
612 let children = node
613 .children()
614 .filter(|node| node.is_element())
615 .map(Source::Node);
616
617 let attributes = node.attributes().map(Source::Attribute);
618
619 let content = once(Source::Content(*node));
620
621 Ok(children.chain(attributes).chain(content))
622 }
623
624 fn siblings(&self) -> Result<impl Iterator<Item = Node<'de, 'de>>, Error> {
625 let node = self.node()?;
626
627 let tag_name = node.tag_name();
628
629 Ok(node.next_siblings().filter(move |node| {
630 let tag_name1 = node.tag_name();
631
632 if O::NAMESPACES && tag_name.namespace() != tag_name1.namespace() {
633 return false;
634 }
635
636 tag_name.name() == tag_name1.name()
637 }))
638 }
639
640 fn text(&self) -> &'de str {
641 match self.source {
642 Source::Node(node) | Source::Content(node) => node.text().unwrap_or_default(),
643 Source::Attribute(attr) => attr.value(),
644 Source::Missing => Default::default(),
645 }
646 }
647
648 fn parse<T>(&self, err: fn(T::Err) -> Error) -> Result<T, Error>
649 where
650 T: FromStr,
651 {
652 self.text().trim().parse().map_err(err)
653 }
654}
655
656impl<'de, O> de::Deserializer<'de> for Deserializer<'de, '_, '_, O>
657where
658 O: Options,
659{
660 type Error = Error;
661
662 fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
663 where
664 V: de::Visitor<'de>,
665 {
666 visitor.visit_bool(self.parse(Error::ParseBool)?)
667 }
668
669 fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
670 where
671 V: de::Visitor<'de>,
672 {
673 visitor.visit_i8(self.parse(Error::ParseInt)?)
674 }
675
676 fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
677 where
678 V: de::Visitor<'de>,
679 {
680 visitor.visit_i16(self.parse(Error::ParseInt)?)
681 }
682
683 fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
684 where
685 V: de::Visitor<'de>,
686 {
687 visitor.visit_i32(self.parse(Error::ParseInt)?)
688 }
689
690 fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
691 where
692 V: de::Visitor<'de>,
693 {
694 visitor.visit_i64(self.parse(Error::ParseInt)?)
695 }
696
697 fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
698 where
699 V: de::Visitor<'de>,
700 {
701 visitor.visit_u8(self.parse(Error::ParseInt)?)
702 }
703
704 fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
705 where
706 V: de::Visitor<'de>,
707 {
708 visitor.visit_u16(self.parse(Error::ParseInt)?)
709 }
710
711 fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
712 where
713 V: de::Visitor<'de>,
714 {
715 visitor.visit_u32(self.parse(Error::ParseInt)?)
716 }
717
718 fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
719 where
720 V: de::Visitor<'de>,
721 {
722 visitor.visit_u64(self.parse(Error::ParseInt)?)
723 }
724
725 fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
726 where
727 V: de::Visitor<'de>,
728 {
729 visitor.visit_f32(self.parse(Error::ParseFloat)?)
730 }
731
732 fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
733 where
734 V: de::Visitor<'de>,
735 {
736 visitor.visit_f64(self.parse(Error::ParseFloat)?)
737 }
738
739 fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
740 where
741 V: de::Visitor<'de>,
742 {
743 visitor.visit_char(self.parse(Error::ParseChar)?)
744 }
745
746 fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
747 where
748 V: de::Visitor<'de>,
749 {
750 visitor.visit_borrowed_str(self.text())
751 }
752
753 fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
754 where
755 V: de::Visitor<'de>,
756 {
757 self.deserialize_str(visitor)
758 }
759
760 fn deserialize_bytes<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
761 where
762 V: de::Visitor<'de>,
763 {
764 Err(Error::NotSupported)
765 }
766
767 fn deserialize_byte_buf<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
768 where
769 V: de::Visitor<'de>,
770 {
771 Err(Error::NotSupported)
772 }
773
774 fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
775 where
776 V: de::Visitor<'de>,
777 {
778 visitor.visit_some(self)
779 }
780
781 fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
782 where
783 V: de::Visitor<'de>,
784 {
785 visitor.visit_unit()
786 }
787
788 fn deserialize_unit_struct<V>(
789 self,
790 _name: &'static str,
791 visitor: V,
792 ) -> Result<V::Value, Self::Error>
793 where
794 V: de::Visitor<'de>,
795 {
796 self.deserialize_unit(visitor)
797 }
798
799 fn deserialize_newtype_struct<V>(
800 self,
801 _name: &'static str,
802 visitor: V,
803 ) -> Result<V::Value, Self::Error>
804 where
805 V: de::Visitor<'de>,
806 {
807 visitor.visit_newtype_struct(self)
808 }
809
810 fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
811 where
812 V: de::Visitor<'de>,
813 {
814 visitor.visit_seq(SeqAccess {
815 source: self.siblings()?,
816 temp: self.temp,
817 options: PhantomData::<O>,
818 })
819 }
820
821 fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
822 where
823 V: de::Visitor<'de>,
824 {
825 self.deserialize_seq(visitor)
826 }
827
828 fn deserialize_tuple_struct<V>(
829 self,
830 _name: &'static str,
831 _len: usize,
832 visitor: V,
833 ) -> Result<V::Value, Self::Error>
834 where
835 V: de::Visitor<'de>,
836 {
837 self.deserialize_seq(visitor)
838 }
839
840 fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
841 where
842 V: de::Visitor<'de>,
843 {
844 if O::ONLY_CHILDREN {
845 visitor.visit_map(MapAccess {
846 source: self.children()?.peekable(),
847 temp: self.temp,
848 options: PhantomData::<O>,
849 })
850 } else {
851 visitor.visit_map(MapAccess {
852 source: self.children_and_attributes()?.peekable(),
853 temp: self.temp,
854 options: PhantomData::<O>,
855 })
856 }
857 }
858
859 fn deserialize_struct<V>(
860 self,
861 #[allow(unused_variables)] name: &'static str,
862 _fields: &'static [&'static str],
863 visitor: V,
864 ) -> Result<V::Value, Self::Error>
865 where
866 V: de::Visitor<'de>,
867 {
868 #[cfg(feature = "raw-node")]
869 let res =
870 raw_node::deserialize_struct(self, name, move |this| this.deserialize_map(visitor));
871
872 #[cfg(not(feature = "raw-node"))]
873 let res = self.deserialize_map(visitor);
874
875 res
876 }
877
878 fn deserialize_enum<V>(
879 self,
880 _name: &'static str,
881 variants: &'static [&'static str],
882 visitor: V,
883 ) -> Result<V::Value, Self::Error>
884 where
885 V: de::Visitor<'de>,
886 {
887 if O::ONLY_CHILDREN {
888 visitor.visit_enum(EnumAccess {
889 source: self.children()?,
890 variants,
891 temp: self.temp,
892 options: PhantomData::<O>,
893 })
894 } else {
895 visitor.visit_enum(EnumAccess {
896 source: self.children_and_attributes()?,
897 variants,
898 temp: self.temp,
899 options: PhantomData::<O>,
900 })
901 }
902 }
903
904 fn deserialize_identifier<V>(mut self, visitor: V) -> Result<V::Value, Self::Error>
905 where
906 V: de::Visitor<'de>,
907 {
908 visitor.visit_str(self.name())
909 }
910
911 fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
912 where
913 V: de::Visitor<'de>,
914 {
915 Err(Error::NotSupported)
916 }
917
918 fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
919 where
920 V: de::Visitor<'de>,
921 {
922 self.deserialize_unit(visitor)
923 }
924}
925
926struct SeqAccess<'de, 'temp, I, O>
927where
928 I: Iterator<Item = Node<'de, 'de>>,
929{
930 source: I,
931 temp: &'temp mut Temp,
932 options: PhantomData<O>,
933}
934
935impl<'de, I, O> de::SeqAccess<'de> for SeqAccess<'de, '_, I, O>
936where
937 I: Iterator<Item = Node<'de, 'de>>,
938 O: Options,
939{
940 type Error = Error;
941
942 fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
943 where
944 T: de::DeserializeSeed<'de>,
945 {
946 match self.source.next() {
947 None => Ok(None),
948 Some(node) => {
949 self.temp.visited.insert(node.id().get_usize());
950
951 let deserializer = Deserializer {
952 source: Source::Node(node),
953 temp: &mut *self.temp,
954 options: PhantomData::<O>,
955 };
956 seed.deserialize(deserializer).map(Some)
957 }
958 }
959 }
960}
961
962struct MapAccess<'de, 'input: 'de, 'temp, I, O>
963where
964 I: Iterator<Item = Source<'de, 'input>>,
965{
966 source: Peekable<I>,
967 temp: &'temp mut Temp,
968 options: PhantomData<O>,
969}
970
971impl<'de, 'input, I, O> de::MapAccess<'de> for MapAccess<'de, 'input, '_, I, O>
972where
973 I: Iterator<Item = Source<'de, 'input>>,
974 O: Options,
975{
976 type Error = Error;
977
978 fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
979 where
980 K: de::DeserializeSeed<'de>,
981 {
982 loop {
983 match self.source.peek() {
984 None => return Ok(None),
985 Some(source) => {
986 if let Source::Node(node) = source {
987 if self.temp.visited.contains(node.id().get_usize()) {
988 self.source.next().unwrap();
989 continue;
990 }
991 }
992
993 let deserailizer = Deserializer {
994 source: *source,
995 temp: &mut *self.temp,
996 options: PhantomData::<O>,
997 };
998 return seed.deserialize(deserailizer).map(Some);
999 }
1000 }
1001 }
1002 }
1003
1004 fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
1005 where
1006 V: de::DeserializeSeed<'de>,
1007 {
1008 let source = self.source.next().unwrap();
1009
1010 let deserializer = Deserializer {
1011 source,
1012 temp: &mut *self.temp,
1013 options: PhantomData::<O>,
1014 };
1015 seed.deserialize(deserializer)
1016 }
1017}
1018
1019struct EnumAccess<'de, 'input: 'de, 'temp, I, O>
1020where
1021 I: Iterator<Item = Source<'de, 'input>>,
1022{
1023 source: I,
1024 variants: &'static [&'static str],
1025 temp: &'temp mut Temp,
1026 options: PhantomData<O>,
1027}
1028
1029impl<'de, 'input, 'temp, I, O> de::EnumAccess<'de> for EnumAccess<'de, 'input, 'temp, I, O>
1030where
1031 I: Iterator<Item = Source<'de, 'input>>,
1032 O: Options,
1033{
1034 type Error = Error;
1035 type Variant = Deserializer<'de, 'input, 'temp, O>;
1036
1037 fn variant_seed<V>(mut self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error>
1038 where
1039 V: de::DeserializeSeed<'de>,
1040 {
1041 let source = self
1042 .source
1043 .find(|source| {
1044 self.variants
1045 .contains(&source.name::<O>(&mut self.temp.buffer))
1046 })
1047 .unwrap_or(Source::Missing);
1048
1049 let deserializer = Deserializer {
1050 source,
1051 temp: &mut *self.temp,
1052 options: PhantomData::<O>,
1053 };
1054 let value = seed.deserialize(deserializer)?;
1055
1056 let deserializer = Deserializer {
1057 source,
1058 temp: &mut *self.temp,
1059 options: PhantomData::<O>,
1060 };
1061 Ok((value, deserializer))
1062 }
1063}
1064
1065impl<'de, O> de::VariantAccess<'de> for Deserializer<'de, '_, '_, O>
1066where
1067 O: Options,
1068{
1069 type Error = Error;
1070
1071 fn unit_variant(self) -> Result<(), Self::Error> {
1072 Ok(())
1073 }
1074
1075 fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
1076 where
1077 T: de::DeserializeSeed<'de>,
1078 {
1079 seed.deserialize(self)
1080 }
1081
1082 fn tuple_variant<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
1083 where
1084 V: de::Visitor<'de>,
1085 {
1086 de::Deserializer::deserialize_tuple(self, len, visitor)
1087 }
1088
1089 fn struct_variant<V>(
1090 self,
1091 fields: &'static [&'static str],
1092 visitor: V,
1093 ) -> Result<V::Value, Self::Error>
1094 where
1095 V: de::Visitor<'de>,
1096 {
1097 de::Deserializer::deserialize_struct(self, "", fields, visitor)
1098 }
1099}
1100
1101#[derive(Debug)]
1103pub enum Error {
1104 MissingNode,
1106 ParseXml(XmlError),
1108 ParseBool(ParseBoolError),
1110 ParseInt(ParseIntError),
1112 ParseFloat(ParseFloatError),
1114 ParseChar(ParseCharError),
1116 NotSupported,
1118 Custom(String),
1120}
1121
1122impl de::Error for Error {
1123 fn custom<T: fmt::Display>(msg: T) -> Self {
1124 Self::Custom(msg.to_string())
1125 }
1126}
1127
1128impl fmt::Display for Error {
1129 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1130 match self {
1131 Self::MissingNode => write!(fmt, "missing node"),
1132 Self::ParseXml(err) => write!(fmt, "XML parse error: {err}"),
1133 Self::ParseBool(err) => write!(fmt, "bool parse error: {err}"),
1134 Self::ParseInt(err) => write!(fmt, "int parse error: {err}"),
1135 Self::ParseFloat(err) => write!(fmt, "float parse error: {err}"),
1136 Self::ParseChar(err) => write!(fmt, "char parse error: {err}"),
1137 Self::NotSupported => write!(fmt, "not supported"),
1138 Self::Custom(msg) => write!(fmt, "custom error: {msg}"),
1139 }
1140 }
1141}
1142
1143impl StdError for Error {
1144 fn source(&self) -> Option<&(dyn StdError + 'static)> {
1145 match self {
1146 Self::ParseXml(err) => Some(err),
1147 Self::ParseBool(err) => Some(err),
1148 Self::ParseInt(err) => Some(err),
1149 Self::ParseFloat(err) => Some(err),
1150 Self::ParseChar(err) => Some(err),
1151 _ => None,
1152 }
1153 }
1154}
1155
1156#[cfg(test)]
1157mod tests {
1158 use super::*;
1159
1160 use serde::Deserialize;
1161
1162 #[test]
1163 fn parse_bool() {
1164 let val = from_str::<bool>("<root>false</root>").unwrap();
1165 assert!(!val);
1166 let val = from_str::<bool>("<root>\n\ttrue\n</root>").unwrap();
1167 assert!(val);
1168
1169 let res = from_str::<bool>("<root>foobar</root>");
1170 assert!(matches!(res, Err(Error::ParseBool(_err))));
1171 }
1172
1173 #[test]
1174 fn parse_char() {
1175 let val = from_str::<char>("<root>x</root>").unwrap();
1176 assert_eq!(val, 'x');
1177 let val = from_str::<char>("<root>\n\ty\n</root>").unwrap();
1178 assert_eq!(val, 'y');
1179
1180 let res = from_str::<char>("<root>xyz</root>");
1181 assert!(matches!(res, Err(Error::ParseChar(_err))));
1182 }
1183
1184 #[test]
1185 fn empty_text() {
1186 let val = from_str::<String>("<root></root>").unwrap();
1187 assert!(val.is_empty());
1188 }
1189
1190 #[test]
1191 fn children_and_attributes() {
1192 #[derive(Deserialize)]
1193 struct Root {
1194 attr: i32,
1195 child: u64,
1196 }
1197
1198 let val = from_str::<Root>(r#"<root attr="23"><child>42</child></root>"#).unwrap();
1199 assert_eq!(val.attr, 23);
1200 assert_eq!(val.child, 42);
1201 }
1202
1203 #[test]
1204 fn children_with_attributes() {
1205 #[derive(Deserialize)]
1206 struct Root {
1207 child: Child,
1208 }
1209
1210 #[derive(Deserialize)]
1211 struct Child {
1212 attr: i32,
1213 #[serde(rename = "#content")]
1214 text: u64,
1215 }
1216
1217 let val = from_str::<Root>(r#"<root><child attr="23">42</child></root>"#).unwrap();
1218 assert_eq!(val.child.attr, 23);
1219 assert_eq!(val.child.text, 42);
1220 }
1221
1222 #[test]
1223 fn multiple_children() {
1224 #[derive(Deserialize)]
1225 struct Root {
1226 child: Vec<i32>,
1227 another_child: String,
1228 }
1229
1230 let val = from_str::<Root>(r#"<root><child>23</child><another_child>foobar</another_child><child>42</child></root>"#).unwrap();
1231 assert_eq!(val.child, [23, 42]);
1232 assert_eq!(val.another_child, "foobar");
1233 }
1234
1235 #[test]
1236 fn multiple_lists_of_multiple_children() {
1237 #[derive(Deserialize)]
1238 struct Root {
1239 child: Vec<i32>,
1240 another_child: Vec<String>,
1241 }
1242
1243 let val = from_str::<Root>(r#"<root><child>23</child><another_child>foo</another_child><child>42</child><another_child>bar</another_child></root>"#).unwrap();
1244 assert_eq!(val.child, [23, 42]);
1245 assert_eq!(val.another_child, ["foo", "bar"]);
1246 }
1247
1248 #[test]
1249 fn zero_of_multiple_children() {
1250 #[derive(Deserialize)]
1251 struct Root {
1252 #[serde(default)]
1253 child: Vec<i32>,
1254 }
1255
1256 let val = from_str::<Root>(r#"<root></root>"#).unwrap();
1257 assert_eq!(val.child, []);
1258 }
1259
1260 #[test]
1261 fn optional_child() {
1262 #[derive(Deserialize)]
1263 struct Root {
1264 child: Option<f32>,
1265 }
1266
1267 let val = from_str::<Root>(r#"<root><child>23.42</child></root>"#).unwrap();
1268 assert_eq!(val.child, Some(23.42));
1269
1270 let val = from_str::<Root>(r#"<root></root>"#).unwrap();
1271 assert_eq!(val.child, None);
1272 }
1273
1274 #[test]
1275 fn optional_attribute() {
1276 #[derive(Deserialize)]
1277 struct Root {
1278 attr: Option<f64>,
1279 }
1280
1281 let val = from_str::<Root>(r#"<root attr="23.42"></root>"#).unwrap();
1282 assert_eq!(val.attr, Some(23.42));
1283
1284 let val = from_str::<Root>(r#"<root></root>"#).unwrap();
1285 assert_eq!(val.attr, None);
1286 }
1287
1288 #[test]
1289 fn child_variants() {
1290 #[derive(Debug, PartialEq, Deserialize)]
1291 enum Root {
1292 Foo(Foo),
1293 Bar(Bar),
1294 }
1295
1296 #[derive(Debug, PartialEq, Deserialize)]
1297 struct Foo {
1298 attr: i64,
1299 }
1300
1301 #[derive(Debug, PartialEq, Deserialize)]
1302 struct Bar {
1303 child: u32,
1304 }
1305
1306 let val = from_str::<Root>(r#"<root><Foo attr="23" /></root>"#).unwrap();
1307 assert_eq!(val, Root::Foo(Foo { attr: 23 }));
1308
1309 let val = from_str::<Root>(r#"<root><Bar><child>42</child></Bar></root>"#).unwrap();
1310 assert_eq!(val, Root::Bar(Bar { child: 42 }));
1311 }
1312
1313 #[test]
1314 fn attribute_variants() {
1315 #[derive(Debug, PartialEq, Deserialize)]
1316 enum Root {
1317 Foo(u32),
1318 Bar(i64),
1319 }
1320
1321 let val = from_str::<Root>(r#"<root Foo="23" />"#).unwrap();
1322 assert_eq!(val, Root::Foo(23));
1323
1324 let val = from_str::<Root>(r#"<root Bar="42" />"#).unwrap();
1325 assert_eq!(val, Root::Bar(42));
1326 }
1327
1328 #[test]
1329 fn mixed_enum_and_struct_children() {
1330 #[derive(Debug, PartialEq, Deserialize)]
1331 enum Foobar {
1332 Foo(u32),
1333 Bar(i64),
1334 }
1335
1336 #[derive(Deserialize)]
1337 struct Root {
1338 #[serde(rename = "#content")]
1339 foobar: Foobar,
1340 qux: f32,
1341 }
1342
1343 let val = from_str::<Root>(r#"<root><qux>42.0</qux><Foo>23</Foo></root>"#).unwrap();
1344 assert_eq!(val.foobar, Foobar::Foo(23));
1345 assert_eq!(val.qux, 42.0);
1346 }
1347
1348 #[test]
1349 fn mixed_enum_and_repeated_struct_children() {
1350 #[derive(Debug, PartialEq, Deserialize)]
1351 enum Foobar {
1352 Foo(u32),
1353 Bar(i64),
1354 }
1355
1356 #[derive(Deserialize)]
1357 struct Root {
1358 #[serde(rename = "#content")]
1359 foobar: Foobar,
1360 qux: Vec<f32>,
1361 baz: String,
1362 }
1363
1364 let val = from_str::<Root>(
1365 r#"<root><Bar>42</Bar><qux>1.0</qux><baz>baz</baz><qux>2.0</qux><qux>3.0</qux></root>"#,
1366 )
1367 .unwrap();
1368 assert_eq!(val.foobar, Foobar::Bar(42));
1369 assert_eq!(val.qux, [1.0, 2.0, 3.0]);
1370 assert_eq!(val.baz, "baz");
1371 }
1372
1373 #[test]
1374 fn repeated_enum_and_struct_children() {
1375 #[derive(Debug, PartialEq, Deserialize)]
1376 enum Foobar {
1377 Foo(Vec<u32>),
1378 Bar(i64),
1379 }
1380
1381 #[derive(Deserialize)]
1382 struct Root {
1383 #[serde(rename = "#content")]
1384 foobar: Foobar,
1385 baz: String,
1386 }
1387
1388 let val =
1389 from_str::<Root>(r#"<root><Foo>42</Foo><baz>baz</baz><Foo>23</Foo></root>"#).unwrap();
1390 assert_eq!(val.foobar, Foobar::Foo(vec![42, 23]));
1391 assert_eq!(val.baz, "baz");
1392 }
1393
1394 #[test]
1395 fn borrowed_str() {
1396 let doc = Document::parse("<root><child>foobar</child></root>").unwrap();
1397
1398 #[derive(Deserialize)]
1399 struct Root<'a> {
1400 child: &'a str,
1401 }
1402
1403 let val = from_doc::<Root>(&doc).unwrap();
1404 assert_eq!(val.child, "foobar");
1405 }
1406
1407 #[test]
1408 fn unit_struct() {
1409 #[derive(Deserialize)]
1410 #[allow(dead_code)]
1411 struct Root {
1412 child: Child,
1413 }
1414
1415 #[derive(Deserialize)]
1416 struct Child;
1417
1418 from_str::<Root>(r#"<root><child /></root>"#).unwrap();
1419
1420 from_str::<Root>(r#"<root><child>foobar</child></root>"#).unwrap();
1421 }
1422
1423 #[test]
1424 fn unit_variant() {
1425 #[derive(Debug, Deserialize)]
1426 enum Root {
1427 Child,
1428 }
1429
1430 from_str::<Root>(r#"<root><Child /></root>"#).unwrap();
1431
1432 from_str::<Root>(r#"<root><Child>foobar</Child></root>"#).unwrap();
1433 }
1434
1435 #[test]
1436 fn children_with_namespaces() {
1437 #[derive(Deserialize)]
1438 struct Root {
1439 #[serde(rename = "{http://name.space}child")]
1440 child: u64,
1441 }
1442
1443 let val = defaults()
1444 .namespaces()
1445 .from_str::<Root>(r#"<root xmlns="http://name.space"><child>42</child></root>"#)
1446 .unwrap();
1447 assert_eq!(val.child, 42);
1448
1449 let val = defaults()
1450 .namespaces()
1451 .from_str::<Root>(r#"<root xmlns:namespace="http://name.space"><namespace:child>42</namespace:child></root>"#)
1452 .unwrap();
1453 assert_eq!(val.child, 42);
1454 }
1455
1456 #[test]
1457 fn attributes_with_namespaces() {
1458 #[derive(Deserialize)]
1459 struct Root {
1460 #[serde(rename = "{http://name.space}attr")]
1461 attr: i32,
1462 }
1463
1464 let val = defaults()
1465 .namespaces()
1466 .from_str::<Root>(
1467 r#"<root xmlns:namespace="http://name.space" namespace:attr="23"></root>"#,
1468 )
1469 .unwrap();
1470 assert_eq!(val.attr, 23);
1471 }
1472
1473 #[test]
1474 fn prefixed_attributes() {
1475 #[derive(Deserialize)]
1476 struct Root {
1477 #[serde(rename = "@attr")]
1478 attr: i32,
1479 }
1480
1481 let val = defaults()
1482 .prefix_attr()
1483 .from_str::<Root>(r#"<root attr="23"></root>"#)
1484 .unwrap();
1485 assert_eq!(val.attr, 23);
1486 }
1487
1488 #[test]
1489 fn prefixed_attributes_with_namespaces() {
1490 #[derive(Deserialize)]
1491 struct Root {
1492 #[serde(rename = "@{http://name.space}attr")]
1493 attr: i32,
1494 }
1495
1496 let val = defaults()
1497 .namespaces()
1498 .prefix_attr()
1499 .from_str::<Root>(
1500 r#"<root xmlns:namespace="http://name.space" namespace:attr="23"></root>"#,
1501 )
1502 .unwrap();
1503 assert_eq!(val.attr, 23);
1504 }
1505
1506 #[test]
1507 fn only_children_skips_attributes() {
1508 #[derive(Deserialize)]
1509 struct Root {
1510 child: u64,
1511 attr: Option<i32>,
1512 }
1513
1514 let val = defaults()
1515 .from_str::<Root>(r#"<root attr="23"><child>42</child></root>"#)
1516 .unwrap();
1517 assert_eq!(val.child, 42);
1518 assert_eq!(val.attr, Some(23));
1519
1520 let val = defaults()
1521 .only_children()
1522 .from_str::<Root>(r#"<root attr="23"><child>42</child></root>"#)
1523 .unwrap();
1524 assert_eq!(val.child, 42);
1525 assert_eq!(val.attr, None);
1526 }
1527
1528 #[test]
1529 fn only_children_skips_content() {
1530 #[derive(Deserialize)]
1531 struct Root {
1532 child: u64,
1533 #[serde(rename = "#content")]
1534 text: Option<String>,
1535 }
1536
1537 let val = defaults()
1538 .from_str::<Root>(r#"<root>text<child>42</child></root>"#)
1539 .unwrap();
1540 assert_eq!(val.child, 42);
1541 assert_eq!(val.text.as_deref(), Some("text"));
1542
1543 let val = defaults()
1544 .only_children()
1545 .from_str::<Root>(r#"<root>text<child>42</child></root>"#)
1546 .unwrap();
1547 assert_eq!(val.child, 42);
1548 assert_eq!(val.text.as_deref(), None);
1549 }
1550
1551 #[test]
1552 fn repeated_namespaced_elements() {
1553 #[derive(Deserialize)]
1554 struct Root {
1555 #[serde(rename = "{http://foo}child")]
1556 foo: Vec<u64>,
1557 #[serde(rename = "{http://bar}child")]
1558 bar: Vec<u64>,
1559 }
1560
1561 let val = defaults()
1562 .namespaces()
1563 .from_str::<Root>(
1564 r#"<root xmlns:foo="http://foo" xmlns:bar="http://bar">
1565 <foo:child>1</foo:child>
1566 <bar:child>2</bar:child>
1567 <bar:child>3</bar:child>
1568 <foo:child>4</foo:child>
1569</root>"#,
1570 )
1571 .unwrap();
1572 assert_eq!(val.foo, [1, 4]);
1573 assert_eq!(val.bar, [2, 3]);
1574 }
1575
1576 #[test]
1577 fn missing_solves_lack_of_option_backtracking() {
1578 #[derive(Deserialize, Debug, PartialEq)]
1579 struct Root {
1580 #[serde(rename = "#content")]
1581 foo: Foo,
1582 }
1583
1584 #[derive(Deserialize, Debug, PartialEq)]
1585 enum Foo {
1586 Bar(i32),
1587 Baz(f32),
1588 #[serde(rename = "#missing")]
1589 Qux,
1590 }
1591
1592 let val = from_str::<Root>(r#"<root><Bar>42</Bar></root>"#).unwrap();
1593 assert_eq!(val, Root { foo: Foo::Bar(42) });
1594
1595 let val = from_str::<Root>(r#"<root><Baz>2.3</Baz></root>"#).unwrap();
1596 assert_eq!(val, Root { foo: Foo::Baz(2.3) });
1597
1598 let val = from_str::<Root>(r#"<root></root>"#).unwrap();
1599 assert_eq!(val, Root { foo: Foo::Qux });
1600 }
1601}