serde_roxmltree/
lib.rs

1//! Convert [`roxmltree`] documents into [`serde`]-compatible types
2//!
3//! [Owned types][de::DeserializeOwned] can be deserialized directly from XML text using [`from_str`]:
4//!
5//! ```
6//! use serde::Deserialize;
7//! use serde_roxmltree::from_str;
8//!
9//! #[derive(Deserialize)]
10//! struct Record {
11//!     field: String,
12//! }
13//!
14//! let record = from_str::<Record>("<record><field>foobar</field></record>")?;
15//! assert_eq!(record.field, "foobar");
16//! #
17//! # Ok::<(), Box<dyn std::error::Error>>(())
18//! ```
19//!
20//! [Borrowing types][de::Deserialize] must be deserialized from a [`Document`] using [`from_doc`]:
21//!
22//! ```
23//! use roxmltree::Document;
24//! use serde::Deserialize;
25//! use serde_roxmltree::from_doc;
26//!
27//! #[derive(Deserialize)]
28//! struct Record<'a> {
29//!     field: &'a str,
30//! }
31//!
32//! let document = Document::parse("<document><field>foobar</field></document>")?;
33//!
34//! let record = from_doc::<Record>(&document)?;
35//! assert_eq!(record.field, "foobar");
36//! #
37//! # Ok::<(), Box<dyn std::error::Error>>(())
38//! ```
39//!
40//! Subtrees can be captured from the source by enabling the `raw-node` feature and using the [`RawNode`] type.
41//!
42//! Fields of structures map to child elements and attributes:
43//!
44//! ```
45//! use serde::Deserialize;
46//! use serde_roxmltree::from_str;
47//!
48//! #[derive(Deserialize)]
49//! struct Record {
50//!     child: String,
51//!     attribute: i32,
52//! }
53//!
54//! let record = from_str::<Record>(r#"<record attribute="42"><child>foobar</child></record>"#)?;
55//! assert_eq!(record.child, "foobar");
56//! assert_eq!(record.attribute, 42);
57//! #
58//! # Ok::<(), Box<dyn std::error::Error>>(())
59//! ```
60//!
61//! Sequences collect repeated child elements:
62//!
63//! ```
64//! use serde::Deserialize;
65//! use serde_roxmltree::from_str;
66//!
67//! #[derive(Deserialize)]
68//! struct Record {
69//!     field: Vec<String>,
70//! }
71//!
72//! let record = from_str::<Record>("<record><field>foo</field><field>bar</field></record>")?;
73//! assert_eq!(record.field, ["foo", "bar"]);
74//! #
75//! # Ok::<(), Box<dyn std::error::Error>>(())
76//! ```
77//!
78//! Enum variants describe alternatives:
79//!
80//! ```
81//! use serde::Deserialize;
82//! use serde_roxmltree::from_str;
83//!
84//! #[derive(Debug, PartialEq, Deserialize)]
85//! #[serde(rename_all = "lowercase")]
86//! enum Record {
87//!     Float(f32),
88//!     Integer(i32),
89//! }
90//!
91//! let record = from_str::<Record>("<record><float>42.0</float></record>")?;
92//! assert_eq!(record, Record::Float(42.0));
93//!
94//! let record = from_str::<Record>("<record><integer>23</integer></record>")?;
95//! assert_eq!(record, Record::Integer(23));
96//! #
97//! # Ok::<(), Box<dyn std::error::Error>>(())
98//! ```
99//!
100//! The reserved name `#content` is used to flatten one level of the hierarchy and
101//! revisit those nodes and attributes as if embedded inside another struct. This can
102//! useful to handle inner text:
103//!
104//! ```
105//! use serde::Deserialize;
106//! use serde_roxmltree::from_str;
107//!
108//! #[derive(Deserialize)]
109//! struct Record {
110//!     child: Child,
111//! }
112//!
113//! #[derive(Deserialize)]
114//! struct Child {
115//!     #[serde(rename = "#content")]
116//!     text: String,
117//!     attribute: i32,
118//! }
119//!
120//! let record = from_str::<Record>(r#"<record><child attribute="42">foobar</child></record>"#)?;
121//! assert_eq!(record.child.text, "foobar");
122//! assert_eq!(record.child.attribute, 42);
123//! #
124//! # Ok::<(), Box<dyn std::error::Error>>(())
125//! ```
126//!
127//! or partial alternatives:
128//!
129//! ```
130//! use serde::Deserialize;
131//! use serde_roxmltree::from_str;
132//!
133//! #[derive(Debug, PartialEq, Deserialize)]
134//! #[serde(rename_all = "lowercase")]
135//! enum Alternative {
136//!     Float(f32),
137//!     Integer(i32),
138//! }
139//!
140//! #[derive(Debug, PartialEq, Deserialize)]
141//! struct Record {
142//!     #[serde(rename = "#content")]
143//!     alternative: Alternative,
144//!     string: String,
145//! }
146//!
147//! let record = from_str::<Record>("<record><float>42.0</float><string>foo</string></record>")?;
148//! assert_eq!(record.alternative, Alternative::Float(42.0));
149//! assert_eq!(record.string, "foo");
150//!
151//! let record = from_str::<Record>("<record><integer>23</integer><string>bar</string></record>")?;
152//! assert_eq!(record.alternative, Alternative::Integer(23));
153//! assert_eq!(record.string, "bar");
154//! #
155//! # Ok::<(), Box<dyn std::error::Error>>(())
156//! ```
157//!
158//! Optionally, attribute names can be prefixed by `@` to distinguish them from tag names:
159//!
160//! ```
161//! use serde::Deserialize;
162//! use serde_roxmltree::{defaults, from_str, Options};
163//!
164//! #[derive(Deserialize)]
165//! struct Record {
166//!     child: String,
167//!     #[serde(rename = "@attribute")]
168//!     attribute: i32,
169//! }
170//!
171//! let record = defaults().prefix_attr().from_str::<Record>(r#"<record attribute="42"><child>foobar</child></record>"#)?;
172//! assert_eq!(record.child, "foobar");
173//! assert_eq!(record.attribute, 42);
174//! #
175//! # Ok::<(), Box<dyn std::error::Error>>(())
176//! ```
177//!
178//! Support for [namespaces][namespaces] can be enabled via the [`namespaces`][Options::namespaces] option:
179//!
180//! ```
181//! use serde::Deserialize;
182//! use serde_roxmltree::{defaults, from_str, Options};
183//!
184//! let text = r#"<record xmlns:foo="http://foo" xmlns:bar="http://bar">
185//!     <foo:qux>23</foo:qux>
186//!     <bar:qux>42</bar:qux>
187//! </record>"#;
188//!
189//! #[derive(Deserialize)]
190//! struct SomeRecord {
191//!     qux: Vec<i32>,
192//! }
193//!
194//! let record = from_str::<SomeRecord>(text)?;
195//! assert_eq!(record.qux, [23, 42]);
196//!
197//! #[derive(Deserialize)]
198//! struct AnotherRecord {
199//!     #[serde(rename = "{http://foo}qux")]
200//!     some_qux: i32,
201//!     #[serde(rename = "{http://bar}qux")]
202//!     another_qux: i32,
203//! }
204//!
205//! let record = defaults().namespaces().from_str::<AnotherRecord>(text)?;
206//! assert_eq!(record.some_qux, 23);
207//! assert_eq!(record.another_qux, 42);
208//! #
209//! # Ok::<(), Box<dyn std::error::Error>>(())
210//! ```
211//!
212//! [namespaces]: https://www.w3.org/TR/REC-xml-names/
213#![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
240/// Deserialize an instance of type `T` directly from XML text
241pub fn from_str<T>(text: &str) -> Result<T, Error>
242where
243    T: de::DeserializeOwned,
244{
245    defaults().from_str(text)
246}
247
248/// Deserialize an instance of type `T` from a [`roxmltree::Document`]
249pub 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
256/// Deserialize an instance of type `T` from a [`roxmltree::Node`]
257pub 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
264/// Types that represent a set of options
265///
266/// Provides methods to deserialize values using the given options
267/// as well as to change individual options in the set.
268pub trait Options: Sized {
269    /// Deserialize an instance of type `T` directly from XML text using the given options
270    #[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    /// Deserialize an instance of type `T` from a [`roxmltree::Document`] using the given options
280    #[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    /// Deserialize an instance of type `T` from a [`roxmltree::Node`] using the given options
290    #[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    /// Include namespaces when building identifiers
304    ///
305    /// When tags or attributes are part of a namespace,
306    /// their identifiers will have the form `{namespace}name`.
307    fn namespaces(self) -> Namespaces<Self> {
308        Namespaces(PhantomData)
309    }
310
311    /// Prefix attribute names
312    ///
313    /// Attribute names will have the form `@name`
314    /// to distinguish them from tag names.
315    fn prefix_attr(self) -> PrefixAttr<Self> {
316        PrefixAttr(PhantomData)
317    }
318
319    /// Only visit child elements
320    ///
321    /// Does not visit attributes and `#content`
322    /// to improve efficiency when these are irrelevant.
323    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
341/// The default set of options
342pub 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/// Possible errors when converting [`roxmltree`] documents to [`serde`]-compatible types
995#[derive(Debug)]
996pub enum Error {
997    /// A node was expected, but an attribute was given
998    MissingNode,
999    /// At least one child or attribute is required
1000    MissingChildOrAttribute,
1001    /// An error when parsing XML
1002    ParseXml(XmlError),
1003    /// An error when parsing a boolean
1004    ParseBool(ParseBoolError),
1005    /// An error when parsing an integer
1006    ParseInt(ParseIntError),
1007    /// An error when parsing a floating point number
1008    ParseFloat(ParseFloatError),
1009    /// An error when parsing a character
1010    ParseChar(ParseCharError),
1011    /// The type is not supported
1012    NotSupported,
1013    /// A custom error produced by the type
1014    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}