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