quick_xml/de/mod.rs
1//! Serde `Deserializer` module.
2//!
3//! Due to the complexity of the XML standard and the fact that Serde was developed
4//! with JSON in mind, not all Serde concepts apply smoothly to XML. This leads to
5//! that fact that some XML concepts are inexpressible in terms of Serde derives
6//! and may require manual deserialization.
7//!
8//! The most notable restriction is the ability to distinguish between _elements_
9//! and _attributes_, as no other format used by serde has such a conception.
10//!
11//! Due to that the mapping is performed in a best effort manner.
12//!
13//!
14//!
15//! Table of Contents
16//! =================
17//! - [Mapping XML to Rust types](#mapping-xml-to-rust-types)
18//! - [Basics](#basics)
19//! - [Optional attributes and elements](#optional-attributes-and-elements)
20//! - [Choices (`xs:choice` XML Schema type)](#choices-xschoice-xml-schema-type)
21//! - [Sequences (`xs:all` and `xs:sequence` XML Schema types)](#sequences-xsall-and-xssequence-xml-schema-types)
22//! - [Mapping of `xsi:nil`](#mapping-of-xsinil)
23//! - [Generate Rust types from XML](#generate-rust-types-from-xml)
24//! - [Composition Rules](#composition-rules)
25//! - [Enum Representations](#enum-representations)
26//! - [Normal enum variant](#normal-enum-variant)
27//! - [`$text` enum variant](#text-enum-variant)
28//! - [`$text` and `$value` special names](#text-and-value-special-names)
29//! - [`$text`](#text)
30//! - [`$value`](#value)
31//! - [Primitives and sequences of primitives](#primitives-and-sequences-of-primitives)
32//! - [Structs and sequences of structs](#structs-and-sequences-of-structs)
33//! - [Enums and sequences of enums](#enums-and-sequences-of-enums)
34//! - [Frequently Used Patterns](#frequently-used-patterns)
35//! - [`<element>` lists](#element-lists)
36//! - [Overlapped (Out-of-Order) Elements](#overlapped-out-of-order-elements)
37//! - [Internally Tagged Enums](#internally-tagged-enums)
38//!
39//!
40//!
41//! Mapping XML to Rust types
42//! =========================
43//!
44//! Type names are never considered when deserializing, so you can name your
45//! types as you wish. Other general rules:
46//! - `struct` field name could be represented in XML only as an attribute name
47//! or an element name;
48//! - `enum` variant name could be represented in XML only as an attribute name
49//! or an element name;
50//! - the unit struct, unit type `()` and unit enum variant can be deserialized
51//! from any valid XML content:
52//! - attribute and element names;
53//! - attribute and element values;
54//! - text or CDATA content (including mixed text and CDATA content).
55//!
56//! <div style="background:rgba(120,145,255,0.45);padding:0.75em;">
57//!
58//! NOTE: All tests are marked with an `ignore` option, even though they do
59//! compile. This is because rustdoc marks such blocks with an information
60//! icon unlike `no_run` blocks.
61//!
62//! </div>
63//!
64//! <table>
65//! <thead>
66//! <tr><th colspan="2">
67//!
68//! ## Basics
69//!
70//! </th></tr>
71//! <tr><th>To parse all these XML's...</th><th>...use these Rust type(s)</th></tr>
72//! </thead>
73//! <tbody style="vertical-align:top;">
74//! <tr>
75//! <td>
76//! Content of attributes and text / CDATA content of elements (including mixed
77//! text and CDATA content):
78//!
79//! ```xml
80//! <... ...="content" />
81//! ```
82//! ```xml
83//! <...>content</...>
84//! ```
85//! ```xml
86//! <...><![CDATA[content]]></...>
87//! ```
88//! ```xml
89//! <...>text<![CDATA[cdata]]>text</...>
90//! ```
91//! Mixed text / CDATA content represents one logical string, `"textcdatatext"` in that case.
92//! </td>
93//! <td>
94//!
95//! You can use any type that can be deserialized from an `&str`, for example:
96//! - [`String`] and [`&str`]
97//! - [`Cow<str>`]
98//! - [`u32`], [`f32`] and other numeric types
99//! - `enum`s, like
100//! ```
101//! # use pretty_assertions::assert_eq;
102//! # use serde::Deserialize;
103//! # #[derive(Debug, PartialEq)]
104//! #[derive(Deserialize)]
105//! enum Language {
106//! Rust,
107//! Cpp,
108//! #[serde(other)]
109//! Other,
110//! }
111//! # #[derive(Debug, PartialEq, Deserialize)]
112//! # struct X { #[serde(rename = "$text")] x: Language }
113//! # assert_eq!(X { x: Language::Rust }, quick_xml::de::from_str("<x>Rust</x>").unwrap());
114//! # assert_eq!(X { x: Language::Cpp }, quick_xml::de::from_str("<x>C<![CDATA[p]]>p</x>").unwrap());
115//! # assert_eq!(X { x: Language::Other }, quick_xml::de::from_str("<x><![CDATA[other]]></x>").unwrap());
116//! ```
117//!
118//! <div style="background:rgba(120,145,255,0.45);padding:0.75em;">
119//!
120//! NOTE: deserialization to non-owned types (i.e. borrow from the input),
121//! such as `&str`, is possible only if you parse document in the UTF-8
122//! encoding and content does not contain entity references such as `&`,
123//! or character references such as `
`, as well as text content represented
124//! by one piece of [text] or [CDATA] element.
125//! </div>
126//! <!-- TODO: document an error type returned -->
127//!
128//! [text]: Event::Text
129//! [CDATA]: Event::CData
130//! </td>
131//! </tr>
132//! <!-- 2 ===================================================================================== -->
133//! <tr>
134//! <td>
135//!
136//! Content of attributes and text / CDATA content of elements (including mixed
137//! text and CDATA content), which represents a space-delimited lists, as
138//! specified in the XML Schema specification for [`xs:list`] `simpleType`:
139//!
140//! ```xml
141//! <... ...="element1 element2 ..." />
142//! ```
143//! ```xml
144//! <...>
145//! element1
146//! element2
147//! ...
148//! </...>
149//! ```
150//! ```xml
151//! <...><![CDATA[
152//! element1
153//! element2
154//! ...
155//! ]]></...>
156//! ```
157//!
158//! [`xs:list`]: https://www.w3.org/TR/xmlschema11-2/#list-datatypes
159//! </td>
160//! <td>
161//!
162//! Use any type that deserialized using [`deserialize_seq()`] call, for example:
163//!
164//! ```
165//! type List = Vec<u32>;
166//! ```
167//!
168//! See the next row to learn where in your struct definition you should
169//! use that type.
170//!
171//! According to the XML Schema specification, delimiters for elements is one
172//! or more space (`' '`, `'\r'`, `'\n'`, and `'\t'`) character(s).
173//!
174//! <div style="background:rgba(120,145,255,0.45);padding:0.75em;">
175//!
176//! NOTE: according to the XML Schema restrictions, you cannot escape those
177//! white-space characters, so list elements will _never_ contain them.
178//! In practice you will usually use `xs:list`s for lists of numbers or enumerated
179//! values which looks like identifiers in many languages, for example, `item`,
180//! `some_item` or `some-item`, so that shouldn't be a problem.
181//!
182//! NOTE: according to the XML Schema specification, list elements can be
183//! delimited only by spaces. Other delimiters (for example, commas) are not
184//! allowed.
185//!
186//! </div>
187//!
188//! [`deserialize_seq()`]: de::Deserializer::deserialize_seq
189//! </td>
190//! </tr>
191//! <!-- 3 ===================================================================================== -->
192//! <tr>
193//! <td>
194//! A typical XML with attributes. The root tag name does not matter:
195//!
196//! ```xml
197//! <any-tag one="..." two="..."/>
198//! ```
199//! </td>
200//! <td>
201//!
202//! A structure where each XML attribute is mapped to a field with a name
203//! starting with `@`. Because Rust identifiers do not permit the `@` character,
204//! you should use the `#[serde(rename = "@...")]` attribute to rename it.
205//! The name of the struct itself does not matter:
206//!
207//! ```
208//! # use serde::Deserialize;
209//! # type T = ();
210//! # type U = ();
211//! // Get both attributes
212//! # #[derive(Debug, PartialEq)]
213//! #[derive(Deserialize)]
214//! struct AnyName {
215//! #[serde(rename = "@one")]
216//! one: T,
217//!
218//! #[serde(rename = "@two")]
219//! two: U,
220//! }
221//! # quick_xml::de::from_str::<AnyName>(r#"<any-tag one="..." two="..."/>"#).unwrap();
222//! ```
223//! ```
224//! # use serde::Deserialize;
225//! # type T = ();
226//! // Get only the one attribute, ignore the other
227//! # #[derive(Debug, PartialEq)]
228//! #[derive(Deserialize)]
229//! struct AnyName {
230//! #[serde(rename = "@one")]
231//! one: T,
232//! }
233//! # quick_xml::de::from_str::<AnyName>(r#"<any-tag one="..." two="..."/>"#).unwrap();
234//! # quick_xml::de::from_str::<AnyName>(r#"<any-tag one="..."/>"#).unwrap();
235//! # quick_xml::de::from_str::<AnyName>(r#"<any-tag one="..."><one>...</one></any-tag>"#).unwrap();
236//! ```
237//! ```
238//! # use serde::Deserialize;
239//! // Ignore all attributes
240//! // You can also use the `()` type (unit type)
241//! # #[derive(Debug, PartialEq)]
242//! #[derive(Deserialize)]
243//! struct AnyName;
244//! # quick_xml::de::from_str::<AnyName>(r#"<any-tag one="..." two="..."/>"#).unwrap();
245//! # quick_xml::de::from_str::<AnyName>(r#"<any-tag one="..."><one>...</one></any-tag>"#).unwrap();
246//! # quick_xml::de::from_str::<AnyName>(r#"<any-tag><one>...</one><two>...</two></any-tag>"#).unwrap();
247//! ```
248//!
249//! All these structs can be used to deserialize from an XML on the
250//! left side depending on amount of information that you want to get.
251//! Of course, you can combine them with elements extractor structs (see below).
252//!
253//! <div style="background:rgba(120,145,255,0.45);padding:0.75em;">
254//!
255//! NOTE: XML allows you to have an attribute and an element with the same name
256//! inside the one element. quick-xml deals with that by prepending a `@` prefix
257//! to the name of attributes.
258//! </div>
259//! </td>
260//! </tr>
261//! <!-- 4 ===================================================================================== -->
262//! <tr>
263//! <td>
264//! A typical XML with child elements. The root tag name does not matter:
265//!
266//! ```xml
267//! <any-tag>
268//! <one>...</one>
269//! <two>...</two>
270//! </any-tag>
271//! ```
272//! </td>
273//! <td>
274//! A structure where each XML child element is mapped to the field.
275//! Each element name becomes a name of field. The name of the struct itself
276//! does not matter:
277//!
278//! ```
279//! # use serde::Deserialize;
280//! # type T = ();
281//! # type U = ();
282//! // Get both elements
283//! # #[derive(Debug, PartialEq)]
284//! #[derive(Deserialize)]
285//! struct AnyName {
286//! one: T,
287//! two: U,
288//! }
289//! # quick_xml::de::from_str::<AnyName>(r#"<any-tag><one>...</one><two>...</two></any-tag>"#).unwrap();
290//! #
291//! # quick_xml::de::from_str::<AnyName>(r#"<any-tag one="..." two="..."/>"#).unwrap_err();
292//! # quick_xml::de::from_str::<AnyName>(r#"<any-tag one="..."><two>...</two></any-tag>"#).unwrap_err();
293//! ```
294//! ```
295//! # use serde::Deserialize;
296//! # type T = ();
297//! // Get only the one element, ignore the other
298//! # #[derive(Debug, PartialEq)]
299//! #[derive(Deserialize)]
300//! struct AnyName {
301//! one: T,
302//! }
303//! # quick_xml::de::from_str::<AnyName>(r#"<any-tag><one>...</one><two>...</two></any-tag>"#).unwrap();
304//! # quick_xml::de::from_str::<AnyName>(r#"<any-tag one="..."><one>...</one></any-tag>"#).unwrap();
305//! ```
306//! ```
307//! # use serde::Deserialize;
308//! // Ignore all elements
309//! // You can also use the `()` type (unit type)
310//! # #[derive(Debug, PartialEq)]
311//! #[derive(Deserialize)]
312//! struct AnyName;
313//! # quick_xml::de::from_str::<AnyName>(r#"<any-tag one="..." two="..."/>"#).unwrap();
314//! # quick_xml::de::from_str::<AnyName>(r#"<any-tag><one>...</one><two>...</two></any-tag>"#).unwrap();
315//! # quick_xml::de::from_str::<AnyName>(r#"<any-tag one="..."><two>...</two></any-tag>"#).unwrap();
316//! # quick_xml::de::from_str::<AnyName>(r#"<any-tag one="..."><one>...</one></any-tag>"#).unwrap();
317//! ```
318//!
319//! All these structs can be used to deserialize from an XML on the
320//! left side depending on amount of information that you want to get.
321//! Of course, you can combine them with attributes extractor structs (see above).
322//!
323//! <div style="background:rgba(120,145,255,0.45);padding:0.75em;">
324//!
325//! NOTE: XML allows you to have an attribute and an element with the same name
326//! inside the one element. quick-xml deals with that by prepending a `@` prefix
327//! to the name of attributes.
328//! </div>
329//! </td>
330//! </tr>
331//! <!-- 5 ===================================================================================== -->
332//! <tr>
333//! <td>
334//! An XML with an attribute and a child element named equally:
335//!
336//! ```xml
337//! <any-tag field="...">
338//! <field>...</field>
339//! </any-tag>
340//! ```
341//! </td>
342//! <td>
343//!
344//! You MUST specify `#[serde(rename = "@field")]` on a field that will be used
345//! for an attribute:
346//!
347//! ```
348//! # use pretty_assertions::assert_eq;
349//! # use serde::Deserialize;
350//! # type T = ();
351//! # type U = ();
352//! # #[derive(Debug, PartialEq)]
353//! #[derive(Deserialize)]
354//! struct AnyName {
355//! #[serde(rename = "@field")]
356//! attribute: T,
357//! field: U,
358//! }
359//! # assert_eq!(
360//! # AnyName { attribute: (), field: () },
361//! # quick_xml::de::from_str(r#"
362//! # <any-tag field="...">
363//! # <field>...</field>
364//! # </any-tag>
365//! # "#).unwrap(),
366//! # );
367//! ```
368//! </td>
369//! </tr>
370//! <!-- ======================================================================================= -->
371//! <tr><th colspan="2">
372//!
373//! ## Optional attributes and elements
374//!
375//! </th></tr>
376//! <tr><th>To parse all these XML's...</th><th>...use these Rust type(s)</th></tr>
377//! <!-- 6 ===================================================================================== -->
378//! <tr>
379//! <td>
380//! An optional XML attribute that you want to capture.
381//! The root tag name does not matter:
382//!
383//! ```xml
384//! <any-tag optional="..."/>
385//! ```
386//! ```xml
387//! <any-tag/>
388//! ```
389//! </td>
390//! <td>
391//!
392//! A structure with an optional field, renamed according to the requirements
393//! for attributes:
394//!
395//! ```
396//! # use pretty_assertions::assert_eq;
397//! # use serde::Deserialize;
398//! # type T = ();
399//! # #[derive(Debug, PartialEq)]
400//! #[derive(Deserialize)]
401//! struct AnyName {
402//! #[serde(rename = "@optional")]
403//! optional: Option<T>,
404//! }
405//! # assert_eq!(AnyName { optional: Some(()) }, quick_xml::de::from_str(r#"<any-tag optional="..."/>"#).unwrap());
406//! # assert_eq!(AnyName { optional: None }, quick_xml::de::from_str(r#"<any-tag/>"#).unwrap());
407//! ```
408//! When the XML attribute is present, type `T` will be deserialized from
409//! an attribute value (which is a string). Note, that if `T = String` or other
410//! string type, the empty attribute is mapped to a `Some("")`, whereas `None`
411//! represents the missed attribute:
412//! ```xml
413//! <any-tag optional="..."/><!-- Some("...") -->
414//! <any-tag optional=""/> <!-- Some("") -->
415//! <any-tag/> <!-- None -->
416//! ```
417//! <div style="background:rgba(120,145,255,0.45);padding:0.75em;">
418//!
419//! NOTE: The behaviour is not symmetric by default. `None` will be serialized as
420//! `optional=""`. This behaviour is consistent across serde crates. You should add
421//! `#[serde(skip_serializing_if = "Option::is_none")]` attribute to the field to
422//! skip `None`s.
423//! </div>
424//! </td>
425//! </tr>
426//! <!-- 7 ===================================================================================== -->
427//! <tr>
428//! <td>
429//! An optional XML elements that you want to capture.
430//! The root tag name does not matter:
431//!
432//! ```xml
433//! <any-tag/>
434//! <optional>...</optional>
435//! </any-tag>
436//! ```
437//! ```xml
438//! <any-tag/>
439//! <optional/>
440//! </any-tag>
441//! ```
442//! ```xml
443//! <any-tag/>
444//! ```
445//! </td>
446//! <td>
447//!
448//! A structure with an optional field:
449//!
450//! ```
451//! # use pretty_assertions::assert_eq;
452//! # use serde::Deserialize;
453//! # type T = ();
454//! # #[derive(Debug, PartialEq)]
455//! #[derive(Deserialize)]
456//! struct AnyName {
457//! optional: Option<T>,
458//! }
459//! # assert_eq!(AnyName { optional: Some(()) }, quick_xml::de::from_str(r#"<any-tag><optional>...</optional></any-tag>"#).unwrap());
460//! # assert_eq!(AnyName { optional: None }, quick_xml::de::from_str(r#"<any-tag/>"#).unwrap());
461//! ```
462//! When the XML element is present, type `T` will be deserialized from an
463//! element (which is a string or a multi-mapping -- i.e. mapping which can have
464//! duplicated keys).
465//! <div style="background:rgba(120,145,255,0.45);padding:0.75em;">
466//!
467//! NOTE: The behaviour is not symmetric by default. `None` will be serialized as
468//! `<optional/>`. This behaviour is consistent across serde crates. You should add
469//! `#[serde(skip_serializing_if = "Option::is_none")]` attribute to the field to
470//! skip `None`s.
471//!
472//! NOTE: Deserializer will automatically handle a [`xsi:nil`] attribute and set field to `None`.
473//! For more info see [Mapping of `xsi:nil`](#mapping-of-xsinil).
474//! </div>
475//! </td>
476//! </tr>
477//! <!-- ======================================================================================= -->
478//! <tr><th colspan="2">
479//!
480//! ## Choices (`xs:choice` XML Schema type)
481//!
482//! </th></tr>
483//! <tr><th>To parse all these XML's...</th><th>...use these Rust type(s)</th></tr>
484//! <!-- 8 ===================================================================================== -->
485//! <tr>
486//! <td>
487//! An XML with different root tag names, as well as text / CDATA content:
488//!
489//! ```xml
490//! <one field1="...">...</one>
491//! ```
492//! ```xml
493//! <two>
494//! <field2>...</field2>
495//! </two>
496//! ```
497//! ```xml
498//! Text <![CDATA[or (mixed)
499//! CDATA]]> content
500//! ```
501//! </td>
502//! <td>
503//!
504//! An enum where each variant has the name of a possible root tag. The name of
505//! the enum itself does not matter.
506//!
507//! If you need to get the textual content, mark a variant with `#[serde(rename = "$text")]`.
508//!
509//! All these structs can be used to deserialize from any XML on the
510//! left side depending on amount of information that you want to get:
511//!
512//! ```
513//! # use pretty_assertions::assert_eq;
514//! # use serde::Deserialize;
515//! # type T = ();
516//! # type U = ();
517//! # #[derive(Debug, PartialEq)]
518//! #[derive(Deserialize)]
519//! #[serde(rename_all = "snake_case")]
520//! enum AnyName {
521//! One { #[serde(rename = "@field1")] field1: T },
522//! Two { field2: U },
523//!
524//! /// Use unit variant, if you do not care of a content.
525//! /// You can use tuple variant if you want to parse
526//! /// textual content as an xs:list.
527//! /// Struct variants are will pass a string to the
528//! /// struct enum variant visitor, which typically
529//! /// returns Err(Custom)
530//! #[serde(rename = "$text")]
531//! Text(String),
532//! }
533//! # assert_eq!(AnyName::One { field1: () }, quick_xml::de::from_str(r#"<one field1="...">...</one>"#).unwrap());
534//! # assert_eq!(AnyName::Two { field2: () }, quick_xml::de::from_str(r#"<two><field2>...</field2></two>"#).unwrap());
535//! # assert_eq!(AnyName::Text("text cdata ".into()), quick_xml::de::from_str(r#"text <![CDATA[ cdata ]]>"#).unwrap());
536//! ```
537//! ```
538//! # use pretty_assertions::assert_eq;
539//! # use serde::Deserialize;
540//! # type T = ();
541//! # #[derive(Debug, PartialEq)]
542//! #[derive(Deserialize)]
543//! struct Two {
544//! field2: T,
545//! }
546//! # #[derive(Debug, PartialEq)]
547//! #[derive(Deserialize)]
548//! #[serde(rename_all = "snake_case")]
549//! enum AnyName {
550//! // `field1` content discarded
551//! One,
552//! Two(Two),
553//! #[serde(rename = "$text")]
554//! Text,
555//! }
556//! # assert_eq!(AnyName::One, quick_xml::de::from_str(r#"<one field1="...">...</one>"#).unwrap());
557//! # assert_eq!(AnyName::Two(Two { field2: () }), quick_xml::de::from_str(r#"<two><field2>...</field2></two>"#).unwrap());
558//! # assert_eq!(AnyName::Text, quick_xml::de::from_str(r#"text <![CDATA[ cdata ]]>"#).unwrap());
559//! ```
560//! ```
561//! # use pretty_assertions::assert_eq;
562//! # use serde::Deserialize;
563//! # #[derive(Debug, PartialEq)]
564//! #[derive(Deserialize)]
565//! #[serde(rename_all = "snake_case")]
566//! enum AnyName {
567//! One,
568//! // the <two> and textual content will be mapped to this
569//! #[serde(other)]
570//! Other,
571//! }
572//! # assert_eq!(AnyName::One, quick_xml::de::from_str(r#"<one field1="...">...</one>"#).unwrap());
573//! # assert_eq!(AnyName::Other, quick_xml::de::from_str(r#"<two><field2>...</field2></two>"#).unwrap());
574//! # assert_eq!(AnyName::Other, quick_xml::de::from_str(r#"text <![CDATA[ cdata ]]>"#).unwrap());
575//! ```
576//! <div style="background:rgba(120,145,255,0.45);padding:0.75em;">
577//!
578//! NOTE: You should have variants for all possible tag names in your enum
579//! or have an `#[serde(other)]` variant.
580//! <!-- TODO: document an error type if that requirement is violated -->
581//! </div>
582//! </td>
583//! </tr>
584//! <!-- 9 ===================================================================================== -->
585//! <tr>
586//! <td>
587//!
588//! `<xs:choice>` embedded in the other element, and at the same time you want
589//! to get access to other attributes that can appear in the same container
590//! (`<any-tag>`). Also this case can be described, as if you want to choose
591//! Rust enum variant based on a tag name:
592//!
593//! ```xml
594//! <any-tag field="...">
595//! <one>...</one>
596//! </any-tag>
597//! ```
598//! ```xml
599//! <any-tag field="...">
600//! <two>...</two>
601//! </any-tag>
602//! ```
603//! ```xml
604//! <any-tag field="...">
605//! Text <![CDATA[or (mixed)
606//! CDATA]]> content
607//! </any-tag>
608//! ```
609//! </td>
610//! <td>
611//!
612//! A structure with a field which type is an `enum`.
613//!
614//! If you need to get a textual content, mark a variant with `#[serde(rename = "$text")]`.
615//!
616//! Names of the enum, struct, and struct field with `Choice` type does not matter:
617//!
618//! ```
619//! # use pretty_assertions::assert_eq;
620//! # use serde::Deserialize;
621//! # type T = ();
622//! # #[derive(Debug, PartialEq)]
623//! #[derive(Deserialize)]
624//! #[serde(rename_all = "snake_case")]
625//! enum Choice {
626//! One,
627//! Two,
628//!
629//! /// Use unit variant, if you do not care of a content.
630//! /// You can use tuple variant if you want to parse
631//! /// textual content as an xs:list.
632//! /// Struct variants are will pass a string to the
633//! /// struct enum variant visitor, which typically
634//! /// returns Err(Custom)
635//! #[serde(rename = "$text")]
636//! Text(String),
637//! }
638//! # #[derive(Debug, PartialEq)]
639//! #[derive(Deserialize)]
640//! struct AnyName {
641//! #[serde(rename = "@field")]
642//! field: T,
643//!
644//! #[serde(rename = "$value")]
645//! any_name: Choice,
646//! }
647//! # assert_eq!(
648//! # AnyName { field: (), any_name: Choice::One },
649//! # quick_xml::de::from_str(r#"<any-tag field="..."><one>...</one></any-tag>"#).unwrap(),
650//! # );
651//! # assert_eq!(
652//! # AnyName { field: (), any_name: Choice::Two },
653//! # quick_xml::de::from_str(r#"<any-tag field="..."><two>...</two></any-tag>"#).unwrap(),
654//! # );
655//! # assert_eq!(
656//! # AnyName { field: (), any_name: Choice::Text("text cdata ".into()) },
657//! # quick_xml::de::from_str(r#"<any-tag field="...">text <![CDATA[ cdata ]]></any-tag>"#).unwrap(),
658//! # );
659//! ```
660//! </td>
661//! </tr>
662//! <!-- 10 ==================================================================================== -->
663//! <tr>
664//! <td>
665//!
666//! `<xs:choice>` embedded in the other element, and at the same time you want
667//! to get access to other elements that can appear in the same container
668//! (`<any-tag>`). Also this case can be described, as if you want to choose
669//! Rust enum variant based on a tag name:
670//!
671//! ```xml
672//! <any-tag>
673//! <field>...</field>
674//! <one>...</one>
675//! </any-tag>
676//! ```
677//! ```xml
678//! <any-tag>
679//! <two>...</two>
680//! <field>...</field>
681//! </any-tag>
682//! ```
683//! </td>
684//! <td>
685//!
686//! A structure with a field which type is an `enum`.
687//!
688//! Names of the enum, struct, and struct field with `Choice` type does not matter:
689//!
690//! ```
691//! # use pretty_assertions::assert_eq;
692//! # use serde::Deserialize;
693//! # type T = ();
694//! # #[derive(Debug, PartialEq)]
695//! #[derive(Deserialize)]
696//! #[serde(rename_all = "snake_case")]
697//! enum Choice {
698//! One,
699//! Two,
700//! }
701//! # #[derive(Debug, PartialEq)]
702//! #[derive(Deserialize)]
703//! struct AnyName {
704//! field: T,
705//!
706//! #[serde(rename = "$value")]
707//! any_name: Choice,
708//! }
709//! # assert_eq!(
710//! # AnyName { field: (), any_name: Choice::One },
711//! # quick_xml::de::from_str(r#"<any-tag><field>...</field><one>...</one></any-tag>"#).unwrap(),
712//! # );
713//! # assert_eq!(
714//! # AnyName { field: (), any_name: Choice::Two },
715//! # quick_xml::de::from_str(r#"<any-tag><two>...</two><field>...</field></any-tag>"#).unwrap(),
716//! # );
717//! ```
718//!
719//! <div style="background:rgba(120,145,255,0.45);padding:0.75em;">
720//!
721//! NOTE: if your `Choice` enum would contain an `#[serde(other)]`
722//! variant, element `<field>` will be mapped to the `field` and not to the enum
723//! variant.
724//! </div>
725//!
726//! </td>
727//! </tr>
728//! <!-- 11 ==================================================================================== -->
729//! <tr>
730//! <td>
731//!
732//! `<xs:choice>` encapsulated in other element with a fixed name:
733//!
734//! ```xml
735//! <any-tag field="...">
736//! <choice>
737//! <one>...</one>
738//! </choice>
739//! </any-tag>
740//! ```
741//! ```xml
742//! <any-tag field="...">
743//! <choice>
744//! <two>...</two>
745//! </choice>
746//! </any-tag>
747//! ```
748//! </td>
749//! <td>
750//!
751//! A structure with a field of an intermediate type with one field of `enum` type.
752//! Actually, this example is not necessary, because you can construct it by yourself
753//! using the composition rules that were described above. However the XML construction
754//! described here is very common, so it is shown explicitly.
755//!
756//! Names of the enum and struct does not matter:
757//!
758//! ```
759//! # use pretty_assertions::assert_eq;
760//! # use serde::Deserialize;
761//! # type T = ();
762//! # #[derive(Debug, PartialEq)]
763//! #[derive(Deserialize)]
764//! #[serde(rename_all = "snake_case")]
765//! enum Choice {
766//! One,
767//! Two,
768//! }
769//! # #[derive(Debug, PartialEq)]
770//! #[derive(Deserialize)]
771//! struct Holder {
772//! #[serde(rename = "$value")]
773//! any_name: Choice,
774//! }
775//! # #[derive(Debug, PartialEq)]
776//! #[derive(Deserialize)]
777//! struct AnyName {
778//! #[serde(rename = "@field")]
779//! field: T,
780//!
781//! choice: Holder,
782//! }
783//! # assert_eq!(
784//! # AnyName { field: (), choice: Holder { any_name: Choice::One } },
785//! # quick_xml::de::from_str(r#"<any-tag field="..."><choice><one>...</one></choice></any-tag>"#).unwrap(),
786//! # );
787//! # assert_eq!(
788//! # AnyName { field: (), choice: Holder { any_name: Choice::Two } },
789//! # quick_xml::de::from_str(r#"<any-tag field="..."><choice><two>...</two></choice></any-tag>"#).unwrap(),
790//! # );
791//! ```
792//! </td>
793//! </tr>
794//! <!-- 12 ==================================================================================== -->
795//! <tr>
796//! <td>
797//!
798//! `<xs:choice>` encapsulated in other element with a fixed name:
799//!
800//! ```xml
801//! <any-tag>
802//! <field>...</field>
803//! <choice>
804//! <one>...</one>
805//! </choice>
806//! </any-tag>
807//! ```
808//! ```xml
809//! <any-tag>
810//! <choice>
811//! <two>...</two>
812//! </choice>
813//! <field>...</field>
814//! </any-tag>
815//! ```
816//! </td>
817//! <td>
818//!
819//! A structure with a field of an intermediate type with one field of `enum` type.
820//! Actually, this example is not necessary, because you can construct it by yourself
821//! using the composition rules that were described above. However the XML construction
822//! described here is very common, so it is shown explicitly.
823//!
824//! Names of the enum and struct does not matter:
825//!
826//! ```
827//! # use pretty_assertions::assert_eq;
828//! # use serde::Deserialize;
829//! # type T = ();
830//! # #[derive(Debug, PartialEq)]
831//! #[derive(Deserialize)]
832//! #[serde(rename_all = "snake_case")]
833//! enum Choice {
834//! One,
835//! Two,
836//! }
837//! # #[derive(Debug, PartialEq)]
838//! #[derive(Deserialize)]
839//! struct Holder {
840//! #[serde(rename = "$value")]
841//! any_name: Choice,
842//! }
843//! # #[derive(Debug, PartialEq)]
844//! #[derive(Deserialize)]
845//! struct AnyName {
846//! field: T,
847//!
848//! choice: Holder,
849//! }
850//! # assert_eq!(
851//! # AnyName { field: (), choice: Holder { any_name: Choice::One } },
852//! # quick_xml::de::from_str(r#"<any-tag><field>...</field><choice><one>...</one></choice></any-tag>"#).unwrap(),
853//! # );
854//! # assert_eq!(
855//! # AnyName { field: (), choice: Holder { any_name: Choice::Two } },
856//! # quick_xml::de::from_str(r#"<any-tag><choice><two>...</two></choice><field>...</field></any-tag>"#).unwrap(),
857//! # );
858//! ```
859//! </td>
860//! </tr>
861//! <!-- ======================================================================================== -->
862//! <tr><th colspan="2">
863//!
864//! ## Sequences (`xs:all` and `xs:sequence` XML Schema types)
865//!
866//! </th></tr>
867//! <tr><th>To parse all these XML's...</th><th>...use these Rust type(s)</th></tr>
868//! <!-- 13 ==================================================================================== -->
869//! <tr>
870//! <td>
871//! A sequence inside of a tag without a dedicated name:
872//!
873//! ```xml
874//! <any-tag/>
875//! ```
876//! ```xml
877//! <any-tag>
878//! <item/>
879//! </any-tag>
880//! ```
881//! ```xml
882//! <any-tag>
883//! <item/>
884//! <item/>
885//! <item/>
886//! </any-tag>
887//! ```
888//! </td>
889//! <td>
890//!
891//! A structure with a field which is a sequence type, for example, [`Vec`].
892//! Because XML syntax does not distinguish between empty sequences and missed
893//! elements, we should indicate that on the Rust side, because serde will require
894//! that field `item` exists. You can do that in two possible ways:
895//!
896//! Use the `#[serde(default)]` attribute for a [field] or the entire [struct]:
897//! ```
898//! # use pretty_assertions::assert_eq;
899//! # use serde::Deserialize;
900//! # type Item = ();
901//! # #[derive(Debug, PartialEq)]
902//! #[derive(Deserialize)]
903//! struct AnyName {
904//! #[serde(default)]
905//! item: Vec<Item>,
906//! }
907//! # assert_eq!(
908//! # AnyName { item: vec![] },
909//! # quick_xml::de::from_str(r#"<any-tag/>"#).unwrap(),
910//! # );
911//! # assert_eq!(
912//! # AnyName { item: vec![()] },
913//! # quick_xml::de::from_str(r#"<any-tag><item/></any-tag>"#).unwrap(),
914//! # );
915//! # assert_eq!(
916//! # AnyName { item: vec![(), (), ()] },
917//! # quick_xml::de::from_str(r#"<any-tag><item/><item/><item/></any-tag>"#).unwrap(),
918//! # );
919//! ```
920//!
921//! Use the [`Option`]. In that case inner array will always contains at least one
922//! element after deserialization:
923//! ```ignore
924//! # use pretty_assertions::assert_eq;
925//! # use serde::Deserialize;
926//! # type Item = ();
927//! # #[derive(Debug, PartialEq)]
928//! #[derive(Deserialize)]
929//! struct AnyName {
930//! item: Option<Vec<Item>>,
931//! }
932//! # assert_eq!(
933//! # AnyName { item: None },
934//! # quick_xml::de::from_str(r#"<any-tag/>"#).unwrap(),
935//! # );
936//! # assert_eq!(
937//! # AnyName { item: Some(vec![()]) },
938//! # quick_xml::de::from_str(r#"<any-tag><item/></any-tag>"#).unwrap(),
939//! # );
940//! # assert_eq!(
941//! # AnyName { item: Some(vec![(), (), ()]) },
942//! # quick_xml::de::from_str(r#"<any-tag><item/><item/><item/></any-tag>"#).unwrap(),
943//! # );
944//! ```
945//!
946//! See also [Frequently Used Patterns](#element-lists).
947//!
948//! [field]: https://serde.rs/field-attrs.html#default
949//! [struct]: https://serde.rs/container-attrs.html#default
950//! </td>
951//! </tr>
952//! <!-- 14 ==================================================================================== -->
953//! <tr>
954//! <td>
955//! A sequence with a strict order, probably with mixed content
956//! (text / CDATA and tags):
957//!
958//! ```xml
959//! <one>...</one>
960//! text
961//! <![CDATA[cdata]]>
962//! <two>...</two>
963//! <one>...</one>
964//! ```
965//! <div style="background:rgba(120,145,255,0.45);padding:0.75em;">
966//!
967//! NOTE: this is just an example for showing mapping. XML does not allow
968//! multiple root tags -- you should wrap the sequence into a tag.
969//! </div>
970//! </td>
971//! <td>
972//!
973//! All elements mapped to the heterogeneous sequential type: tuple or named tuple.
974//! Each element of the tuple should be able to be deserialized from the nested
975//! element content (`...`), except the enum types which would be deserialized
976//! from the full element (`<one>...</one>`), so they could use the element name
977//! to choose the right variant:
978//!
979//! ```
980//! # use pretty_assertions::assert_eq;
981//! # use serde::Deserialize;
982//! # type One = ();
983//! # type Two = ();
984//! # /*
985//! type One = ...;
986//! type Two = ...;
987//! # */
988//! # #[derive(Debug, PartialEq)]
989//! #[derive(Deserialize)]
990//! struct AnyName(One, String, Two, One);
991//! # assert_eq!(
992//! # AnyName((), "text cdata".into(), (), ()),
993//! # quick_xml::de::from_str(r#"<one>...</one>text <![CDATA[cdata]]><two>...</two><one>...</one>"#).unwrap(),
994//! # );
995//! ```
996//! ```
997//! # use pretty_assertions::assert_eq;
998//! # use serde::Deserialize;
999//! # #[derive(Debug, PartialEq)]
1000//! #[derive(Deserialize)]
1001//! #[serde(rename_all = "snake_case")]
1002//! enum Choice {
1003//! One,
1004//! }
1005//! # type Two = ();
1006//! # /*
1007//! type Two = ...;
1008//! # */
1009//! type AnyName = (Choice, String, Two, Choice);
1010//! # assert_eq!(
1011//! # (Choice::One, "text cdata".to_string(), (), Choice::One),
1012//! # quick_xml::de::from_str(r#"<one>...</one>text <![CDATA[cdata]]><two>...</two><one>...</one>"#).unwrap(),
1013//! # );
1014//! ```
1015//! <div style="background:rgba(120,145,255,0.45);padding:0.75em;">
1016//!
1017//! NOTE: consequent text and CDATA nodes are merged into the one text node,
1018//! so you cannot have two adjacent string types in your sequence.
1019//!
1020//! NOTE: In the case that the list might contain tags that are overlapped with
1021//! tags that do not correspond to the list you should add the feature [`overlapped-lists`].
1022//! </div>
1023//! </td>
1024//! </tr>
1025//! <!-- 15 ==================================================================================== -->
1026//! <tr>
1027//! <td>
1028//! A sequence with a non-strict order, probably with a mixed content
1029//! (text / CDATA and tags).
1030//!
1031//! ```xml
1032//! <one>...</one>
1033//! text
1034//! <![CDATA[cdata]]>
1035//! <two>...</two>
1036//! <one>...</one>
1037//! ```
1038//! <div style="background:rgba(120,145,255,0.45);padding:0.75em;">
1039//!
1040//! NOTE: this is just an example for showing mapping. XML does not allow
1041//! multiple root tags -- you should wrap the sequence into a tag.
1042//! </div>
1043//! </td>
1044//! <td>
1045//! A homogeneous sequence of elements with a fixed or dynamic size:
1046//!
1047//! ```
1048//! # use pretty_assertions::assert_eq;
1049//! # use serde::Deserialize;
1050//! # #[derive(Debug, PartialEq)]
1051//! #[derive(Deserialize)]
1052//! #[serde(rename_all = "snake_case")]
1053//! enum Choice {
1054//! One,
1055//! Two,
1056//! #[serde(other)]
1057//! Other,
1058//! }
1059//! type AnyName = [Choice; 4];
1060//! # assert_eq!(
1061//! # [Choice::One, Choice::Other, Choice::Two, Choice::One],
1062//! # quick_xml::de::from_str::<AnyName>(r#"<one>...</one>text <![CDATA[cdata]]><two>...</two><one>...</one>"#).unwrap(),
1063//! # );
1064//! ```
1065//! ```
1066//! # use pretty_assertions::assert_eq;
1067//! # use serde::Deserialize;
1068//! # #[derive(Debug, PartialEq)]
1069//! #[derive(Deserialize)]
1070//! #[serde(rename_all = "snake_case")]
1071//! enum Choice {
1072//! One,
1073//! Two,
1074//! #[serde(rename = "$text")]
1075//! Other(String),
1076//! }
1077//! type AnyName = Vec<Choice>;
1078//! # assert_eq!(
1079//! # vec![
1080//! # Choice::One,
1081//! # Choice::Other("text cdata".into()),
1082//! # Choice::Two,
1083//! # Choice::One,
1084//! # ],
1085//! # quick_xml::de::from_str::<AnyName>(r#"<one>...</one>text <![CDATA[cdata]]><two>...</two><one>...</one>"#).unwrap(),
1086//! # );
1087//! ```
1088//! <div style="background:rgba(120,145,255,0.45);padding:0.75em;">
1089//!
1090//! NOTE: consequent text and CDATA nodes are merged into the one text node,
1091//! so you cannot have two adjacent string types in your sequence.
1092//! </div>
1093//! </td>
1094//! </tr>
1095//! <!-- 16 ==================================================================================== -->
1096//! <tr>
1097//! <td>
1098//! A sequence with a strict order, probably with a mixed content,
1099//! (text and tags) inside of the other element:
1100//!
1101//! ```xml
1102//! <any-tag attribute="...">
1103//! <one>...</one>
1104//! text
1105//! <![CDATA[cdata]]>
1106//! <two>...</two>
1107//! <one>...</one>
1108//! </any-tag>
1109//! ```
1110//! </td>
1111//! <td>
1112//!
1113//! A structure where all child elements mapped to the one field which have
1114//! a heterogeneous sequential type: tuple or named tuple. Each element of the
1115//! tuple should be able to be deserialized from the full element (`<one>...</one>`).
1116//!
1117//! You MUST specify `#[serde(rename = "$value")]` on that field:
1118//!
1119//! ```
1120//! # use pretty_assertions::assert_eq;
1121//! # use serde::Deserialize;
1122//! # type One = ();
1123//! # type Two = ();
1124//! # /*
1125//! type One = ...;
1126//! type Two = ...;
1127//! # */
1128//!
1129//! # #[derive(Debug, PartialEq)]
1130//! #[derive(Deserialize)]
1131//! struct AnyName {
1132//! #[serde(rename = "@attribute")]
1133//! # attribute: (),
1134//! # /*
1135//! attribute: ...,
1136//! # */
1137//! // Does not (yet?) supported by the serde
1138//! // https://github.com/serde-rs/serde/issues/1905
1139//! // #[serde(flatten)]
1140//! #[serde(rename = "$value")]
1141//! any_name: (One, String, Two, One),
1142//! }
1143//! # assert_eq!(
1144//! # AnyName { attribute: (), any_name: ((), "text cdata".into(), (), ()) },
1145//! # quick_xml::de::from_str("\
1146//! # <any-tag attribute='...'>\
1147//! # <one>...</one>\
1148//! # text \
1149//! # <![CDATA[cdata]]>\
1150//! # <two>...</two>\
1151//! # <one>...</one>\
1152//! # </any-tag>"
1153//! # ).unwrap(),
1154//! # );
1155//! ```
1156//! ```
1157//! # use pretty_assertions::assert_eq;
1158//! # use serde::Deserialize;
1159//! # type One = ();
1160//! # type Two = ();
1161//! # /*
1162//! type One = ...;
1163//! type Two = ...;
1164//! # */
1165//!
1166//! # #[derive(Debug, PartialEq)]
1167//! #[derive(Deserialize)]
1168//! struct NamedTuple(One, String, Two, One);
1169//!
1170//! # #[derive(Debug, PartialEq)]
1171//! #[derive(Deserialize)]
1172//! struct AnyName {
1173//! #[serde(rename = "@attribute")]
1174//! # attribute: (),
1175//! # /*
1176//! attribute: ...,
1177//! # */
1178//! // Does not (yet?) supported by the serde
1179//! // https://github.com/serde-rs/serde/issues/1905
1180//! // #[serde(flatten)]
1181//! #[serde(rename = "$value")]
1182//! any_name: NamedTuple,
1183//! }
1184//! # assert_eq!(
1185//! # AnyName { attribute: (), any_name: NamedTuple((), "text cdata".into(), (), ()) },
1186//! # quick_xml::de::from_str("\
1187//! # <any-tag attribute='...'>\
1188//! # <one>...</one>\
1189//! # text \
1190//! # <![CDATA[cdata]]>\
1191//! # <two>...</two>\
1192//! # <one>...</one>\
1193//! # </any-tag>"
1194//! # ).unwrap(),
1195//! # );
1196//! ```
1197//! <div style="background:rgba(120,145,255,0.45);padding:0.75em;">
1198//!
1199//! NOTE: consequent text and CDATA nodes are merged into the one text node,
1200//! so you cannot have two adjacent string types in your sequence.
1201//! </div>
1202//! </td>
1203//! </tr>
1204//! <!-- 17 ==================================================================================== -->
1205//! <tr>
1206//! <td>
1207//! A sequence with a non-strict order, probably with a mixed content
1208//! (text / CDATA and tags) inside of the other element:
1209//!
1210//! ```xml
1211//! <any-tag>
1212//! <one>...</one>
1213//! text
1214//! <![CDATA[cdata]]>
1215//! <two>...</two>
1216//! <one>...</one>
1217//! </any-tag>
1218//! ```
1219//! </td>
1220//! <td>
1221//!
1222//! A structure where all child elements mapped to the one field which have
1223//! a homogeneous sequential type: array-like container. A container type `T`
1224//! should be able to be deserialized from the nested element content (`...`),
1225//! except if it is an enum type which would be deserialized from the full
1226//! element (`<one>...</one>`).
1227//!
1228//! You MUST specify `#[serde(rename = "$value")]` on that field:
1229//!
1230//! ```
1231//! # use pretty_assertions::assert_eq;
1232//! # use serde::Deserialize;
1233//! # #[derive(Debug, PartialEq)]
1234//! #[derive(Deserialize)]
1235//! #[serde(rename_all = "snake_case")]
1236//! enum Choice {
1237//! One,
1238//! Two,
1239//! #[serde(rename = "$text")]
1240//! Other(String),
1241//! }
1242//! # #[derive(Debug, PartialEq)]
1243//! #[derive(Deserialize)]
1244//! struct AnyName {
1245//! #[serde(rename = "@attribute")]
1246//! # attribute: (),
1247//! # /*
1248//! attribute: ...,
1249//! # */
1250//! // Does not (yet?) supported by the serde
1251//! // https://github.com/serde-rs/serde/issues/1905
1252//! // #[serde(flatten)]
1253//! #[serde(rename = "$value")]
1254//! any_name: [Choice; 4],
1255//! }
1256//! # assert_eq!(
1257//! # AnyName { attribute: (), any_name: [
1258//! # Choice::One,
1259//! # Choice::Other("text cdata".into()),
1260//! # Choice::Two,
1261//! # Choice::One,
1262//! # ] },
1263//! # quick_xml::de::from_str("\
1264//! # <any-tag attribute='...'>\
1265//! # <one>...</one>\
1266//! # text \
1267//! # <![CDATA[cdata]]>\
1268//! # <two>...</two>\
1269//! # <one>...</one>\
1270//! # </any-tag>"
1271//! # ).unwrap(),
1272//! # );
1273//! ```
1274//! ```
1275//! # use pretty_assertions::assert_eq;
1276//! # use serde::Deserialize;
1277//! # #[derive(Debug, PartialEq)]
1278//! #[derive(Deserialize)]
1279//! #[serde(rename_all = "snake_case")]
1280//! enum Choice {
1281//! One,
1282//! Two,
1283//! #[serde(rename = "$text")]
1284//! Other(String),
1285//! }
1286//! # #[derive(Debug, PartialEq)]
1287//! #[derive(Deserialize)]
1288//! struct AnyName {
1289//! #[serde(rename = "@attribute")]
1290//! # attribute: (),
1291//! # /*
1292//! attribute: ...,
1293//! # */
1294//! // Does not (yet?) supported by the serde
1295//! // https://github.com/serde-rs/serde/issues/1905
1296//! // #[serde(flatten)]
1297//! #[serde(rename = "$value")]
1298//! any_name: Vec<Choice>,
1299//! }
1300//! # assert_eq!(
1301//! # AnyName { attribute: (), any_name: vec![
1302//! # Choice::One,
1303//! # Choice::Other("text cdata".into()),
1304//! # Choice::Two,
1305//! # Choice::One,
1306//! # ] },
1307//! # quick_xml::de::from_str("\
1308//! # <any-tag attribute='...'>\
1309//! # <one>...</one>\
1310//! # text \
1311//! # <![CDATA[cdata]]>\
1312//! # <two>...</two>\
1313//! # <one>...</one>\
1314//! # </any-tag>"
1315//! # ).unwrap(),
1316//! # );
1317//! ```
1318//! <div style="background:rgba(120,145,255,0.45);padding:0.75em;">
1319//!
1320//! NOTE: consequent text and CDATA nodes are merged into the one text node,
1321//! so you cannot have two adjacent string types in your sequence.
1322//! </div>
1323//! </td>
1324//! </tr>
1325//! </tbody>
1326//! </table>
1327//!
1328//!
1329//! Mapping of `xsi:nil`
1330//! ====================
1331//!
1332//! quick-xml supports handling of [`xsi:nil`] special attribute. When field of optional
1333//! type is mapped to the XML element which have `xsi:nil="true"` set, or if that attribute
1334//! is placed on parent XML element, the deserializer will call [`Visitor::visit_none`]
1335//! and skip XML element corresponding to a field.
1336//!
1337//! Examples:
1338//!
1339//! ```
1340//! # use pretty_assertions::assert_eq;
1341//! # use serde::Deserialize;
1342//! #[derive(Deserialize, Debug, PartialEq)]
1343//! struct TypeWithOptionalField {
1344//! element: Option<String>,
1345//! }
1346//!
1347//! assert_eq!(
1348//! TypeWithOptionalField {
1349//! element: None,
1350//! },
1351//! quick_xml::de::from_str("
1352//! <any-tag xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
1353//! <element xsi:nil='true'>Content is skipped because of xsi:nil='true'</element>
1354//! </any-tag>
1355//! ").unwrap(),
1356//! );
1357//! ```
1358//!
1359//! You can capture attributes from the optional type, because ` xsi:nil="true"` elements can have
1360//! attributes:
1361//! ```
1362//! # use pretty_assertions::assert_eq;
1363//! # use serde::Deserialize;
1364//! #[derive(Deserialize, Debug, PartialEq)]
1365//! struct TypeWithOptionalField {
1366//! #[serde(rename = "@attribute")]
1367//! attribute: usize,
1368//!
1369//! element: Option<String>,
1370//! non_optional: String,
1371//! }
1372//!
1373//! assert_eq!(
1374//! TypeWithOptionalField {
1375//! attribute: 42,
1376//! element: None,
1377//! non_optional: "Note, that non-optional fields will be deserialized as usual".to_string(),
1378//! },
1379//! quick_xml::de::from_str("
1380//! <any-tag attribute='42' xsi:nil='true' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
1381//! <element>Content is skipped because of xsi:nil='true'</element>
1382//! <non_optional>Note, that non-optional fields will be deserialized as usual</non_optional>
1383//! </any-tag>
1384//! ").unwrap(),
1385//! );
1386//! ```
1387//!
1388//! Generate Rust types from XML
1389//! ============================
1390//!
1391//! To speed up the creation of Rust types that represent a given XML file you can
1392//! use the [xml_schema_generator](https://github.com/Thomblin/xml_schema_generator).
1393//! It provides a standalone binary and a Rust library that parses one or more XML files
1394//! and generates a collection of structs that are compatible with quick_xml::de.
1395//!
1396//!
1397//!
1398//! Composition Rules
1399//! =================
1400//!
1401//! The XML format is very different from other formats supported by `serde`.
1402//! One such difference it is how data in the serialized form is related to
1403//! the Rust type. Usually each byte in the data can be associated only with
1404//! one field in the data structure. However, XML is an exception.
1405//!
1406//! For example, took this XML:
1407//!
1408//! ```xml
1409//! <any>
1410//! <key attr="value"/>
1411//! </any>
1412//! ```
1413//!
1414//! and try to deserialize it to the struct `AnyName`:
1415//!
1416//! ```no_run
1417//! # use serde::Deserialize;
1418//! #[derive(Deserialize)]
1419//! struct AnyName { // AnyName calls `deserialize_struct` on `<any><key attr="value"/></any>`
1420//! // Used data: ^^^^^^^^^^^^^^^^^^^
1421//! key: Inner, // Inner calls `deserialize_struct` on `<key attr="value"/>`
1422//! // Used data: ^^^^^^^^^^^^
1423//! }
1424//! #[derive(Deserialize)]
1425//! struct Inner {
1426//! #[serde(rename = "@attr")]
1427//! attr: String, // String calls `deserialize_string` on `value`
1428//! // Used data: ^^^^^
1429//! }
1430//! ```
1431//!
1432//! Comments shows what methods of a [`Deserializer`] called by each struct
1433//! `deserialize` method and which input their seen. **Used data** shows, what
1434//! content is actually used for deserializing. As you see, name of the inner
1435//! `<key>` tag used both as a map key / outer struct field name and as part
1436//! of the inner struct (although _value_ of the tag, i.e. `key` is not used
1437//! by it).
1438//!
1439//!
1440//!
1441//! Enum Representations
1442//! ====================
1443//!
1444//! `quick-xml` represents enums differently in normal fields, `$text` fields and
1445//! `$value` fields. A normal representation is compatible with serde's adjacent
1446//! and internal tags feature -- tag for adjacently and internally tagged enums
1447//! are serialized using [`Serializer::serialize_unit_variant`] and deserialized
1448//! using [`Deserializer::deserialize_enum`].
1449//!
1450//! Use those simple rules to remember, how enum would be represented in XML:
1451//! - In `$value` field the representation is always the same as top-level representation;
1452//! - In `$text` field the representation is always the same as in normal field,
1453//! but surrounding tags with field name are removed;
1454//! - In normal field the representation is always contains a tag with a field name.
1455//!
1456//! Normal enum variant
1457//! -------------------
1458//!
1459//! To model an `xs:choice` XML construct use `$value` field.
1460//! To model a top-level `xs:choice` just use the enum type.
1461//!
1462//! |Kind |Top-level and in `$value` field |In normal field |In `$text` field |
1463//! |-------|-----------------------------------------|---------------------|---------------------|
1464//! |Unit |`<Unit/>` |`<field>Unit</field>`|`Unit` |
1465//! |Newtype|`<Newtype>42</Newtype>` |Err(Custom) [^0] |Err(Custom) [^0] |
1466//! |Tuple |`<Tuple>42</Tuple><Tuple>answer</Tuple>` |Err(Custom) [^0] |Err(Custom) [^0] |
1467//! |Struct |`<Struct><q>42</q><a>answer</a></Struct>`|Err(Custom) [^0] |Err(Custom) [^0] |
1468//!
1469//! `$text` enum variant
1470//! --------------------
1471//!
1472//! |Kind |Top-level and in `$value` field |In normal field |In `$text` field |
1473//! |-------|-----------------------------------------|---------------------|---------------------|
1474//! |Unit |_(empty)_ |`<field/>` |_(empty)_ |
1475//! |Newtype|`42` |Err(Custom) [^0] [^1]|Err(Custom) [^0] [^2]|
1476//! |Tuple |`42 answer` |Err(Custom) [^0] [^3]|Err(Custom) [^0] [^4]|
1477//! |Struct |Err(Custom) [^0] |Err(Custom) [^0] |Err(Custom) [^0] |
1478//!
1479//! [^0]: Error is returned by the deserialized type. In case of derived implementation a `Custom`
1480//! error will be returned, but custom deserialize implementation can successfully deserialize
1481//! value from a string which will be passed to it.
1482//!
1483//! [^1]: If this serialize as `<field>42</field>` then it will be ambiguity during deserialization,
1484//! because it clash with `Unit` representation in normal field.
1485//!
1486//! [^2]: If this serialize as `42` then it will be ambiguity during deserialization,
1487//! because it clash with `Unit` representation in `$text` field.
1488//!
1489//! [^3]: If this serialize as `<field>42 answer</field>` then it will be ambiguity during deserialization,
1490//! because it clash with `Unit` representation in normal field.
1491//!
1492//! [^4]: If this serialize as `42 answer` then it will be ambiguity during deserialization,
1493//! because it clash with `Unit` representation in `$text` field.
1494//!
1495//!
1496//!
1497//! `$text` and `$value` special names
1498//! ==================================
1499//!
1500//! quick-xml supports two special names for fields -- `$text` and `$value`.
1501//! Although they may seem the same, there is a distinction. Two different
1502//! names is required mostly for serialization, because quick-xml should know
1503//! how you want to serialize certain constructs, which could be represented
1504//! through XML in multiple different ways.
1505//!
1506//! The only difference is in how complex types and sequences are serialized.
1507//! If you doubt which one you should select, begin with [`$value`](#value).
1508//!
1509//! If you have both `$text` and `$value` in you struct, then text events will be
1510//! mapped to the `$text` field:
1511//!
1512//! ```
1513//! # use serde::Deserialize;
1514//! # use quick_xml::de::from_str;
1515//! #[derive(Deserialize, PartialEq, Debug)]
1516//! struct TextAndValue {
1517//! #[serde(rename = "$text")]
1518//! text: Option<String>,
1519//!
1520//! #[serde(rename = "$value")]
1521//! value: Option<String>,
1522//! }
1523//!
1524//! let object: TextAndValue = from_str("<AnyName>text <![CDATA[and CDATA]]></AnyName>").unwrap();
1525//! assert_eq!(object, TextAndValue {
1526//! text: Some("text and CDATA".to_string()),
1527//! value: None,
1528//! });
1529//! ```
1530//!
1531//! ## `$text`
1532//! `$text` is used when you want to write your XML as a text or a CDATA content.
1533//! More formally, field with that name represents simple type definition with
1534//! `{variety} = atomic` or `{variety} = union` whose basic members are all atomic,
1535//! as described in the [specification].
1536//!
1537//! As a result, not all types of such fields can be serialized. Only serialization
1538//! of following types are supported:
1539//! - all primitive types (strings, numbers, booleans)
1540//! - unit variants of enumerations (serializes to a name of a variant)
1541//! - newtypes (delegates serialization to inner type)
1542//! - [`Option`] of above (`None` serializes to nothing)
1543//! - sequences (including tuples and tuple variants of enumerations) of above,
1544//! excluding `None` and empty string elements (because it will not be possible
1545//! to deserialize them back). The elements are separated by space(s)
1546//! - unit type `()` and unit structs (serializes to nothing)
1547//!
1548//! Complex types, such as structs and maps, are not supported in this field.
1549//! If you want them, you should use `$value`.
1550//!
1551//! Sequences serialized to a space-delimited string, that is why only certain
1552//! types are allowed in this mode:
1553//!
1554//! ```
1555//! # use serde::{Deserialize, Serialize};
1556//! # use quick_xml::de::from_str;
1557//! # use quick_xml::se::to_string;
1558//! #[derive(Deserialize, Serialize, PartialEq, Debug)]
1559//! struct AnyName {
1560//! #[serde(rename = "$text")]
1561//! field: Vec<usize>,
1562//! }
1563//!
1564//! let obj = AnyName { field: vec![1, 2, 3] };
1565//! let xml = to_string(&obj).unwrap();
1566//! assert_eq!(xml, "<AnyName>1 2 3</AnyName>");
1567//!
1568//! let object: AnyName = from_str(&xml).unwrap();
1569//! assert_eq!(object, obj);
1570//! ```
1571//!
1572//! ## `$value`
1573//! <div style="background:rgba(120,145,255,0.45);padding:0.75em;">
1574//!
1575//! NOTE: a name `#content` would better explain the purpose of that field,
1576//! but `$value` is used for compatibility with other XML serde crates, which
1577//! uses that name. This will allow you to switch XML crates more smoothly if required.
1578//! </div>
1579//!
1580//! The representation of primitive types in `$value` does not differ from their
1581//! representation in `$text` fields. The difference is how sequences are serialized
1582//! and deserialized. `$value` serializes each sequence item as a separate XML element.
1583//! How the name of the XML element is chosen depends on the field's type. For
1584//! `enum`s, the variant name is used. For `struct`s, the name of the `struct`
1585//! is used.
1586//!
1587//! During deserialization, if the `$value` field is an enum, then the variant's
1588//! name is matched against. That's **not** the case with structs, however, since
1589//! `serde` does not expose type names of nested fields. This does mean that **any**
1590//! type could be deserialized into a `$value` struct-type field, so long as the
1591//! struct's fields have compatible types (or are captured as text by `String`
1592//! or similar-behaving types). This can be handy when using generic types in fields
1593//! where one knows in advance what to expect. If you do not know what to expect,
1594//! however, prefer an enum with all possible variants.
1595//!
1596//! Unit structs and unit type `()` serialize to nothing and can be deserialized
1597//! from any content.
1598//!
1599//! Serialization and deserialization of `$value` field performed as usual, except
1600//! that name for an XML element will be given by the serialized type, instead of
1601//! field. The latter allow to serialize enumerated types, where variant is encoded
1602//! as a tag name, and, so, represent an XSD `xs:choice` schema by the Rust `enum`.
1603//!
1604//! In the example below, field will be serialized as `<field/>`, because elements
1605//! get their names from the field name. It cannot be deserialized, because `Enum`
1606//! expects elements `<A/>`, `<B/>` or `<C/>`, but `AnyName` looked only for `<field/>`:
1607//!
1608//! ```
1609//! # use serde::{Deserialize, Serialize};
1610//! # use pretty_assertions::assert_eq;
1611//! # #[derive(PartialEq, Debug)]
1612//! #[derive(Deserialize, Serialize)]
1613//! enum Enum { A, B, C }
1614//!
1615//! # #[derive(PartialEq, Debug)]
1616//! #[derive(Deserialize, Serialize)]
1617//! struct AnyName {
1618//! // <field>A</field>, <field>B</field>, or <field>C</field>
1619//! field: Enum,
1620//! }
1621//! # assert_eq!(
1622//! # quick_xml::se::to_string(&AnyName { field: Enum::A }).unwrap(),
1623//! # "<AnyName><field>A</field></AnyName>",
1624//! # );
1625//! # assert_eq!(
1626//! # AnyName { field: Enum::B },
1627//! # quick_xml::de::from_str("<root><field>B</field></root>").unwrap(),
1628//! # );
1629//! ```
1630//!
1631//! If you rename field to `$value`, then `field` would be serialized as `<A/>`,
1632//! `<B/>` or `<C/>`, depending on the its content. It is also possible to
1633//! deserialize it from the same elements:
1634//!
1635//! ```
1636//! # use serde::{Deserialize, Serialize};
1637//! # use pretty_assertions::assert_eq;
1638//! # #[derive(Deserialize, Serialize, PartialEq, Debug)]
1639//! # enum Enum { A, B, C }
1640//! #
1641//! # #[derive(PartialEq, Debug)]
1642//! #[derive(Deserialize, Serialize)]
1643//! struct AnyName {
1644//! // <A/>, <B/> or <C/>
1645//! #[serde(rename = "$value")]
1646//! field: Enum,
1647//! }
1648//! # assert_eq!(
1649//! # quick_xml::se::to_string(&AnyName { field: Enum::A }).unwrap(),
1650//! # "<AnyName><A/></AnyName>",
1651//! # );
1652//! # assert_eq!(
1653//! # AnyName { field: Enum::B },
1654//! # quick_xml::de::from_str("<root><B/></root>").unwrap(),
1655//! # );
1656//! ```
1657//!
1658//! The next example demonstrates how generic types can be used in conjunction
1659//! with `$value`-named fields to allow the reuse of wrapping structs. A common
1660//! example use case for this feature is SOAP messages, which can be commmonly
1661//! found wrapped around `<soapenv:Envelope> ... </soapenv:Envelope>`.
1662//!
1663//! ```rust
1664//! # use pretty_assertions::assert_eq;
1665//! # use quick_xml::de::from_str;
1666//! # use quick_xml::se::to_string;
1667//! # use serde::{Deserialize, Serialize};
1668//! #
1669//! #[derive(Deserialize, Serialize, PartialEq, Debug)]
1670//! struct Envelope<T> {
1671//! body: Body<T>,
1672//! }
1673//!
1674//! #[derive(Deserialize, Serialize, PartialEq, Debug)]
1675//! struct Body<T> {
1676//! #[serde(rename = "$value")]
1677//! inner: T,
1678//! }
1679//!
1680//! #[derive(Serialize, PartialEq, Debug)]
1681//! struct Example {
1682//! a: i32,
1683//! }
1684//!
1685//! assert_eq!(
1686//! to_string(&Envelope { body: Body { inner: Example { a: 42 } } }).unwrap(),
1687//! // Notice how `inner` is not present in the XML
1688//! "<Envelope><body><Example><a>42</a></Example></body></Envelope>",
1689//! );
1690//!
1691//! #[derive(Deserialize, PartialEq, Debug)]
1692//! struct AnotherExample {
1693//! a: i32,
1694//! }
1695//!
1696//! assert_eq!(
1697//! // Notice that tag the name does nothing for struct in `$value` field
1698//! Envelope { body: Body { inner: AnotherExample { a: 42 } } },
1699//! from_str("<Envelope><body><Example><a>42</a></Example></body></Envelope>").unwrap(),
1700//! );
1701//! ```
1702//!
1703//! ### Primitives and sequences of primitives
1704//!
1705//! Sequences serialized to a list of elements. Note, that types that does not
1706//! produce their own tag (i. e. primitives) will produce [`SeError::Unsupported`]
1707//! if they contains more that one element, because such sequence cannot be
1708//! deserialized to the same value:
1709//!
1710//! ```
1711//! # use serde::{Deserialize, Serialize};
1712//! # use pretty_assertions::assert_eq;
1713//! # use quick_xml::de::from_str;
1714//! # use quick_xml::se::to_string;
1715//! #[derive(Deserialize, Serialize, PartialEq, Debug)]
1716//! struct AnyName {
1717//! #[serde(rename = "$value")]
1718//! field: Vec<usize>,
1719//! }
1720//!
1721//! let obj = AnyName { field: vec![1, 2, 3] };
1722//! // If this object were serialized, it would be represented as "<AnyName>123</AnyName>"
1723//! to_string(&obj).unwrap_err();
1724//!
1725//! let object: AnyName = from_str("<AnyName>123</AnyName>").unwrap();
1726//! assert_eq!(object, AnyName { field: vec![123] });
1727//!
1728//! // `1 2 3` is mapped to a single `usize` element
1729//! // It is impossible to deserialize list of primitives to such field
1730//! from_str::<AnyName>("<AnyName>1 2 3</AnyName>").unwrap_err();
1731//! ```
1732//!
1733//! A particular case of that example is a string `$value` field, which probably
1734//! would be a most used example of that attribute:
1735//!
1736//! ```
1737//! # use serde::{Deserialize, Serialize};
1738//! # use pretty_assertions::assert_eq;
1739//! # use quick_xml::de::from_str;
1740//! # use quick_xml::se::to_string;
1741//! #[derive(Deserialize, Serialize, PartialEq, Debug)]
1742//! struct AnyName {
1743//! #[serde(rename = "$value")]
1744//! field: String,
1745//! }
1746//!
1747//! let obj = AnyName { field: "content".to_string() };
1748//! let xml = to_string(&obj).unwrap();
1749//! assert_eq!(xml, "<AnyName>content</AnyName>");
1750//! ```
1751//!
1752//! ### Structs and sequences of structs
1753//!
1754//! Note, that structures do not have a serializable name as well (name of the
1755//! type is never used), so it is impossible to serialize non-unit struct or
1756//! sequence of non-unit structs in `$value` field. (sequences of) unit structs
1757//! are serialized as empty string, because units itself serializing
1758//! to nothing:
1759//!
1760//! ```
1761//! # use serde::{Deserialize, Serialize};
1762//! # use pretty_assertions::assert_eq;
1763//! # use quick_xml::de::from_str;
1764//! # use quick_xml::se::to_string;
1765//! #[derive(Deserialize, Serialize, PartialEq, Debug)]
1766//! struct Unit;
1767//!
1768//! #[derive(Deserialize, Serialize, PartialEq, Debug)]
1769//! struct AnyName {
1770//! // #[serde(default)] is required to deserialization of empty lists
1771//! // This is a general note, not related to $value
1772//! #[serde(rename = "$value", default)]
1773//! field: Vec<Unit>,
1774//! }
1775//!
1776//! let obj = AnyName { field: vec![Unit, Unit, Unit] };
1777//! let xml = to_string(&obj).unwrap();
1778//! assert_eq!(xml, "<AnyName/>");
1779//!
1780//! let object: AnyName = from_str("<AnyName/>").unwrap();
1781//! assert_eq!(object, AnyName { field: vec![] });
1782//!
1783//! let object: AnyName = from_str("<AnyName></AnyName>").unwrap();
1784//! assert_eq!(object, AnyName { field: vec![] });
1785//!
1786//! let object: AnyName = from_str("<AnyName><A/><B/><C/></AnyName>").unwrap();
1787//! assert_eq!(object, AnyName { field: vec![Unit, Unit, Unit] });
1788//! ```
1789//!
1790//! ### Enums and sequences of enums
1791//!
1792//! Enumerations uses the variant name as an element name:
1793//!
1794//! ```
1795//! # use serde::{Deserialize, Serialize};
1796//! # use pretty_assertions::assert_eq;
1797//! # use quick_xml::de::from_str;
1798//! # use quick_xml::se::to_string;
1799//! #[derive(Deserialize, Serialize, PartialEq, Debug)]
1800//! struct AnyName {
1801//! #[serde(rename = "$value")]
1802//! field: Vec<Enum>,
1803//! }
1804//!
1805//! #[derive(Deserialize, Serialize, PartialEq, Debug)]
1806//! enum Enum { A, B, C }
1807//!
1808//! let obj = AnyName { field: vec![Enum::A, Enum::B, Enum::C] };
1809//! let xml = to_string(&obj).unwrap();
1810//! assert_eq!(
1811//! xml,
1812//! "<AnyName>\
1813//! <A/>\
1814//! <B/>\
1815//! <C/>\
1816//! </AnyName>"
1817//! );
1818//!
1819//! let object: AnyName = from_str(&xml).unwrap();
1820//! assert_eq!(object, obj);
1821//! ```
1822//!
1823//!
1824//!
1825//! Frequently Used Patterns
1826//! ========================
1827//!
1828//! Some XML constructs used so frequent, that it is worth to document the recommended
1829//! way to represent them in the Rust. The sections below describes them.
1830//!
1831//! `<element>` lists
1832//! -----------------
1833//! Many XML formats wrap lists of elements in the additional container,
1834//! although this is not required by the XML rules:
1835//!
1836//! ```xml
1837//! <root>
1838//! <field1/>
1839//! <field2/>
1840//! <list><!-- Container -->
1841//! <element/>
1842//! <element/>
1843//! <element/>
1844//! </list>
1845//! <field3/>
1846//! </root>
1847//! ```
1848//! In this case, there is a great desire to describe this XML in this way:
1849//! ```
1850//! /// Represents <element/>
1851//! type Element = ();
1852//!
1853//! /// Represents <root>...</root>
1854//! struct AnyName {
1855//! // Incorrect
1856//! list: Vec<Element>,
1857//! }
1858//! ```
1859//! This will not work, because potentially `<list>` element can have attributes
1860//! and other elements inside. You should define the struct for the `<list>`
1861//! explicitly, as you do that in the XSD for that XML:
1862//! ```
1863//! /// Represents <element/>
1864//! type Element = ();
1865//!
1866//! /// Represents <root>...</root>
1867//! struct AnyName {
1868//! // Correct
1869//! list: List,
1870//! }
1871//! /// Represents <list>...</list>
1872//! struct List {
1873//! element: Vec<Element>,
1874//! }
1875//! ```
1876//!
1877//! If you want to simplify your API, you could write a simple function for unwrapping
1878//! inner list and apply it via [`deserialize_with`]:
1879//!
1880//! ```
1881//! # use pretty_assertions::assert_eq;
1882//! use quick_xml::de::from_str;
1883//! use serde::{Deserialize, Deserializer};
1884//!
1885//! /// Represents <element/>
1886//! type Element = ();
1887//!
1888//! /// Represents <root>...</root>
1889//! #[derive(Deserialize, Debug, PartialEq)]
1890//! struct AnyName {
1891//! #[serde(deserialize_with = "unwrap_list")]
1892//! list: Vec<Element>,
1893//! }
1894//!
1895//! fn unwrap_list<'de, D>(deserializer: D) -> Result<Vec<Element>, D::Error>
1896//! where
1897//! D: Deserializer<'de>,
1898//! {
1899//! /// Represents <list>...</list>
1900//! #[derive(Deserialize)]
1901//! struct List {
1902//! // default allows empty list
1903//! #[serde(default)]
1904//! element: Vec<Element>,
1905//! }
1906//! Ok(List::deserialize(deserializer)?.element)
1907//! }
1908//!
1909//! assert_eq!(
1910//! AnyName { list: vec![(), (), ()] },
1911//! from_str("
1912//! <root>
1913//! <list>
1914//! <element/>
1915//! <element/>
1916//! <element/>
1917//! </list>
1918//! </root>
1919//! ").unwrap(),
1920//! );
1921//! ```
1922//!
1923//! Instead of writing such functions manually, you also could try <https://lib.rs/crates/serde-query>.
1924//!
1925//! Overlapped (Out-of-Order) Elements
1926//! ----------------------------------
1927//! In the case that the list might contain tags that are overlapped with
1928//! tags that do not correspond to the list (this is a usual case in XML
1929//! documents) like this:
1930//! ```xml
1931//! <any-name>
1932//! <item/>
1933//! <another-item/>
1934//! <item/>
1935//! <item/>
1936//! </any-name>
1937//! ```
1938//! you should enable the [`overlapped-lists`] feature to make it possible
1939//! to deserialize this to:
1940//! ```no_run
1941//! # use serde::Deserialize;
1942//! #[derive(Deserialize)]
1943//! #[serde(rename_all = "kebab-case")]
1944//! struct AnyName {
1945//! item: Vec<()>,
1946//! another_item: (),
1947//! }
1948//! ```
1949//!
1950//!
1951//! Internally Tagged Enums
1952//! -----------------------
1953//! [Tagged enums] are currently not supported because of an issue in the Serde
1954//! design (see [serde#1183] and [quick-xml#586]) and missing optimizations in
1955//! Serde which could be useful for XML parsing ([serde#1495]). This can be worked
1956//! around by manually implementing deserialize with `#[serde(deserialize_with = "func")]`
1957//! or implementing [`Deserialize`], but this can get very tedious very fast for
1958//! files with large amounts of tagged enums. To help with this issue quick-xml
1959//! provides a macro [`impl_deserialize_for_internally_tagged_enum!`]. See the
1960//! macro documentation for details.
1961//!
1962//!
1963//! [`overlapped-lists`]: ../index.html#overlapped-lists
1964//! [specification]: https://www.w3.org/TR/xmlschema11-1/#Simple_Type_Definition
1965//! [`deserialize_with`]: https://serde.rs/field-attrs.html#deserialize_with
1966//! [`xsi:nil`]: https://www.w3.org/TR/xmlschema-1/#xsi_nil
1967//! [`Serializer::serialize_unit_variant`]: serde::Serializer::serialize_unit_variant
1968//! [`Deserializer::deserialize_enum`]: serde::Deserializer::deserialize_enum
1969//! [`SeError::Unsupported`]: crate::errors::serialize::SeError::Unsupported
1970//! [Tagged enums]: https://serde.rs/enum-representations.html#internally-tagged
1971//! [serde#1183]: https://github.com/serde-rs/serde/issues/1183
1972//! [serde#1495]: https://github.com/serde-rs/serde/issues/1495
1973//! [quick-xml#586]: https://github.com/tafia/quick-xml/issues/586
1974//! [`impl_deserialize_for_internally_tagged_enum!`]: crate::impl_deserialize_for_internally_tagged_enum
1975
1976macro_rules! forward_to_simple_type {
1977 ($deserialize:ident, $($mut:tt)?) => {
1978 #[inline]
1979 fn $deserialize<V>($($mut)? self, visitor: V) -> Result<V::Value, DeError>
1980 where
1981 V: Visitor<'de>,
1982 {
1983 SimpleTypeDeserializer::from_text(self.read_string()?).$deserialize(visitor)
1984 }
1985 };
1986}
1987
1988/// Implement deserialization methods for scalar types, such as numbers, strings,
1989/// byte arrays, booleans and identifiers.
1990macro_rules! deserialize_primitives {
1991 ($($mut:tt)?) => {
1992 forward_to_simple_type!(deserialize_i8, $($mut)?);
1993 forward_to_simple_type!(deserialize_i16, $($mut)?);
1994 forward_to_simple_type!(deserialize_i32, $($mut)?);
1995 forward_to_simple_type!(deserialize_i64, $($mut)?);
1996
1997 forward_to_simple_type!(deserialize_u8, $($mut)?);
1998 forward_to_simple_type!(deserialize_u16, $($mut)?);
1999 forward_to_simple_type!(deserialize_u32, $($mut)?);
2000 forward_to_simple_type!(deserialize_u64, $($mut)?);
2001
2002 forward_to_simple_type!(deserialize_i128, $($mut)?);
2003 forward_to_simple_type!(deserialize_u128, $($mut)?);
2004
2005 forward_to_simple_type!(deserialize_f32, $($mut)?);
2006 forward_to_simple_type!(deserialize_f64, $($mut)?);
2007
2008 forward_to_simple_type!(deserialize_bool, $($mut)?);
2009 forward_to_simple_type!(deserialize_char, $($mut)?);
2010
2011 forward_to_simple_type!(deserialize_str, $($mut)?);
2012 forward_to_simple_type!(deserialize_string, $($mut)?);
2013
2014 /// Forwards deserialization to the [`deserialize_any`](#method.deserialize_any).
2015 #[inline]
2016 fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, DeError>
2017 where
2018 V: Visitor<'de>,
2019 {
2020 self.deserialize_any(visitor)
2021 }
2022
2023 /// Forwards deserialization to the [`deserialize_bytes`](#method.deserialize_bytes).
2024 #[inline]
2025 fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, DeError>
2026 where
2027 V: Visitor<'de>,
2028 {
2029 self.deserialize_bytes(visitor)
2030 }
2031
2032 /// Representation of the named units the same as [unnamed units](#method.deserialize_unit).
2033 #[inline]
2034 fn deserialize_unit_struct<V>(
2035 self,
2036 _name: &'static str,
2037 visitor: V,
2038 ) -> Result<V::Value, DeError>
2039 where
2040 V: Visitor<'de>,
2041 {
2042 self.deserialize_unit(visitor)
2043 }
2044
2045 /// Representation of tuples the same as [sequences](#method.deserialize_seq).
2046 #[inline]
2047 fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, DeError>
2048 where
2049 V: Visitor<'de>,
2050 {
2051 self.deserialize_seq(visitor)
2052 }
2053
2054 /// Representation of named tuples the same as [unnamed tuples](#method.deserialize_tuple).
2055 #[inline]
2056 fn deserialize_tuple_struct<V>(
2057 self,
2058 _name: &'static str,
2059 len: usize,
2060 visitor: V,
2061 ) -> Result<V::Value, DeError>
2062 where
2063 V: Visitor<'de>,
2064 {
2065 self.deserialize_tuple(len, visitor)
2066 }
2067
2068 /// Forwards deserialization to the [`deserialize_struct`](#method.deserialize_struct)
2069 /// with empty name and fields.
2070 #[inline]
2071 fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, DeError>
2072 where
2073 V: Visitor<'de>,
2074 {
2075 self.deserialize_struct("", &[], visitor)
2076 }
2077
2078 /// Identifiers represented as [strings](#method.deserialize_str).
2079 #[inline]
2080 fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, DeError>
2081 where
2082 V: Visitor<'de>,
2083 {
2084 self.deserialize_str(visitor)
2085 }
2086
2087 /// Forwards deserialization to the [`deserialize_unit`](#method.deserialize_unit).
2088 #[inline]
2089 fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, DeError>
2090 where
2091 V: Visitor<'de>,
2092 {
2093 self.deserialize_unit(visitor)
2094 }
2095 };
2096}
2097
2098mod attributes;
2099mod key;
2100mod map;
2101mod resolver;
2102mod simple_type;
2103mod text;
2104mod var;
2105
2106pub use self::attributes::AttributesDeserializer;
2107pub use self::resolver::{EntityResolver, PredefinedEntityResolver};
2108pub use self::simple_type::SimpleTypeDeserializer;
2109use crate::XmlVersion;
2110pub use crate::errors::serialize::DeError;
2111
2112use crate::{
2113 de::map::ElementMapAccess,
2114 errors::Error,
2115 escape::{EscapeError, parse_number},
2116 events::{BytesCData, BytesEnd, BytesRef, BytesStart, BytesText, Event},
2117 name::{NamespaceResolver, QName},
2118 reader::{NsReader, Reader},
2119};
2120use serde::de::{
2121 self, Deserialize, DeserializeOwned, DeserializeSeed, IntoDeserializer, SeqAccess, Visitor,
2122};
2123use std::borrow::Cow;
2124#[cfg(feature = "overlapped-lists")]
2125use std::collections::VecDeque;
2126use std::io::BufRead;
2127use std::mem::replace;
2128#[cfg(feature = "overlapped-lists")]
2129use std::num::NonZeroUsize;
2130use std::ops::{Deref, Range};
2131
2132/// Data represented by a text node or a CDATA node. XML markup is not expected
2133pub(crate) const TEXT_KEY: &str = "$text";
2134/// Data represented by any XML markup inside
2135pub(crate) const VALUE_KEY: &str = "$value";
2136
2137/// A function to check whether the character is a whitespace (blank, new line, carriage return or tab).
2138#[inline]
2139const fn is_non_whitespace(ch: char) -> bool {
2140 !matches!(ch, ' ' | '\r' | '\n' | '\t')
2141}
2142
2143/// Decoded and concatenated content of consequent [`Text`] and [`CData`]
2144/// events. _Consequent_ means that events should follow each other or be
2145/// delimited only by (any count of) [`Comment`] or [`PI`] events.
2146///
2147/// Internally text is stored in `Cow<str>`. Cloning of text is cheap while it
2148/// is borrowed and makes copies of data when it is owned.
2149///
2150/// [`Text`]: Event::Text
2151/// [`CData`]: Event::CData
2152/// [`Comment`]: Event::Comment
2153/// [`PI`]: Event::PI
2154#[derive(Clone, Debug, PartialEq, Eq)]
2155pub struct Text<'a> {
2156 /// Untrimmed text after concatenating content of all
2157 /// [`Text`] and [`CData`] events
2158 ///
2159 /// [`Text`]: Event::Text
2160 /// [`CData`]: Event::CData
2161 text: Cow<'a, str>,
2162 /// A range into `text` which contains data after trimming
2163 content: Range<usize>,
2164}
2165
2166impl<'a> Text<'a> {
2167 fn new(text: Cow<'a, str>) -> Self {
2168 let start = text.find(is_non_whitespace).unwrap_or(0);
2169 let end = text.rfind(is_non_whitespace).map_or(0, |i| i + 1);
2170
2171 let content = if start >= end { 0..0 } else { start..end };
2172
2173 Self { text, content }
2174 }
2175
2176 /// Returns text without leading and trailing whitespaces as [defined] by XML specification.
2177 ///
2178 /// If you want to only check if text contains only whitespaces, use [`is_blank`](Self::is_blank),
2179 /// which will not allocate.
2180 ///
2181 /// # Example
2182 ///
2183 /// ```
2184 /// # use quick_xml::de::Text;
2185 /// # use pretty_assertions::assert_eq;
2186 /// #
2187 /// let text = Text::from("");
2188 /// assert_eq!(text.trimmed(), "");
2189 ///
2190 /// let text = Text::from(" \r\n\t ");
2191 /// assert_eq!(text.trimmed(), "");
2192 ///
2193 /// let text = Text::from(" some useful text ");
2194 /// assert_eq!(text.trimmed(), "some useful text");
2195 /// ```
2196 ///
2197 /// [defined]: https://www.w3.org/TR/xml11/#NT-S
2198 pub fn trimmed(&self) -> Cow<'a, str> {
2199 match self.text {
2200 Cow::Borrowed(text) => Cow::Borrowed(&text[self.content.clone()]),
2201 Cow::Owned(ref text) => Cow::Owned(text[self.content.clone()].to_string()),
2202 }
2203 }
2204
2205 /// Returns `true` if text is empty or contains only whitespaces as [defined] by XML specification.
2206 ///
2207 /// # Example
2208 ///
2209 /// ```
2210 /// # use quick_xml::de::Text;
2211 /// # use pretty_assertions::assert_eq;
2212 /// #
2213 /// let text = Text::from("");
2214 /// assert_eq!(text.is_blank(), true);
2215 ///
2216 /// let text = Text::from(" \r\n\t ");
2217 /// assert_eq!(text.is_blank(), true);
2218 ///
2219 /// let text = Text::from(" some useful text ");
2220 /// assert_eq!(text.is_blank(), false);
2221 /// ```
2222 ///
2223 /// [defined]: https://www.w3.org/TR/xml11/#NT-S
2224 pub fn is_blank(&self) -> bool {
2225 self.content.is_empty()
2226 }
2227}
2228
2229impl<'a> Deref for Text<'a> {
2230 type Target = str;
2231
2232 #[inline]
2233 fn deref(&self) -> &Self::Target {
2234 self.text.deref()
2235 }
2236}
2237
2238impl<'a> From<&'a str> for Text<'a> {
2239 #[inline]
2240 fn from(text: &'a str) -> Self {
2241 Self::new(Cow::Borrowed(text))
2242 }
2243}
2244
2245impl<'a> From<String> for Text<'a> {
2246 #[inline]
2247 fn from(text: String) -> Self {
2248 Self::new(Cow::Owned(text))
2249 }
2250}
2251
2252impl<'a> From<Cow<'a, str>> for Text<'a> {
2253 #[inline]
2254 fn from(text: Cow<'a, str>) -> Self {
2255 Self::new(text)
2256 }
2257}
2258
2259////////////////////////////////////////////////////////////////////////////////////////////////////
2260
2261/// Simplified event which contains only these variants that used by deserializer
2262#[derive(Clone, Debug, PartialEq, Eq)]
2263pub enum DeEvent<'a> {
2264 /// Start tag (with attributes) `<tag attr="value">`.
2265 Start(BytesStart<'a>),
2266 /// End tag `</tag>`.
2267 End(BytesEnd<'a>),
2268 /// Decoded and concatenated content of consequent [`Text`] and [`CData`]
2269 /// events. _Consequent_ means that events should follow each other or be
2270 /// delimited only by (any count of) [`Comment`] or [`PI`] events.
2271 ///
2272 /// [`Text`]: Event::Text
2273 /// [`CData`]: Event::CData
2274 /// [`Comment`]: Event::Comment
2275 /// [`PI`]: Event::PI
2276 Text(Text<'a>),
2277 /// End of XML document.
2278 Eof,
2279}
2280
2281////////////////////////////////////////////////////////////////////////////////////////////////////
2282
2283/// Simplified event which contains only these variants that used by deserializer,
2284/// but [`Text`] events not yet fully processed.
2285///
2286/// [`Text`] events should be trimmed if they does not surrounded by the other
2287/// [`Text`] or [`CData`] events. This event contains intermediate state of [`Text`]
2288/// event, where they are trimmed from the start, but not from the end. To trim
2289/// end spaces we should lookahead by one deserializer event (i. e. skip all
2290/// comments and processing instructions).
2291///
2292/// [`Text`]: Event::Text
2293/// [`CData`]: Event::CData
2294#[derive(Clone, Debug, PartialEq, Eq)]
2295pub enum PayloadEvent<'a> {
2296 /// Start tag (with attributes) `<tag attr="value">`.
2297 Start(BytesStart<'a>),
2298 /// End tag `</tag>`.
2299 End(BytesEnd<'a>),
2300 /// Escaped character data between tags.
2301 Text(BytesText<'a>),
2302 /// Unescaped character data stored in `<![CDATA[...]]>`.
2303 CData(BytesCData<'a>),
2304 /// Document type definition data (DTD) stored in `<!DOCTYPE ...>`.
2305 DocType(BytesText<'a>),
2306 /// Reference `&ref;` in the textual data.
2307 GeneralRef(BytesRef<'a>),
2308 /// End of XML document.
2309 Eof,
2310}
2311
2312impl<'a> PayloadEvent<'a> {
2313 /// Ensures that all data is owned to extend the object's lifetime if necessary.
2314 #[inline]
2315 fn into_owned(self) -> PayloadEvent<'static> {
2316 match self {
2317 PayloadEvent::Start(e) => PayloadEvent::Start(e.into_owned()),
2318 PayloadEvent::End(e) => PayloadEvent::End(e.into_owned()),
2319 PayloadEvent::Text(e) => PayloadEvent::Text(e.into_owned()),
2320 PayloadEvent::CData(e) => PayloadEvent::CData(e.into_owned()),
2321 PayloadEvent::DocType(e) => PayloadEvent::DocType(e.into_owned()),
2322 PayloadEvent::GeneralRef(e) => PayloadEvent::GeneralRef(e.into_owned()),
2323 PayloadEvent::Eof => PayloadEvent::Eof,
2324 }
2325 }
2326}
2327
2328/// An intermediate reader that consumes [`PayloadEvent`]s and produces final [`DeEvent`]s.
2329/// [`PayloadEvent::Text`] events, that followed by any event except
2330/// [`PayloadEvent::Text`] or [`PayloadEvent::CData`], are trimmed from the end.
2331struct XmlReader<'i, R: XmlRead<'i>, E: EntityResolver = PredefinedEntityResolver> {
2332 /// A source of low-level XML events
2333 reader: R,
2334 /// Intermediate event, that could be returned by the next call to `next()`.
2335 /// If that is the `Text` event then leading spaces already trimmed, but
2336 /// trailing spaces is not. Before the event will be returned, trimming of
2337 /// the spaces could be necessary
2338 lookahead: Result<PayloadEvent<'i>, DeError>,
2339
2340 /// Used to resolve unknown entities that would otherwise cause the parser
2341 /// to return an [`EscapeError::UnrecognizedEntity`] error.
2342 ///
2343 /// [`EscapeError::UnrecognizedEntity`]: crate::escape::EscapeError::UnrecognizedEntity
2344 entity_resolver: E,
2345}
2346
2347impl<'i, R: XmlRead<'i>, E: EntityResolver> XmlReader<'i, R, E> {
2348 fn new(mut reader: R, entity_resolver: E) -> Self {
2349 // Lookahead by one event immediately, so we do not need to check in the
2350 // loop if we need lookahead or not
2351 let lookahead = reader.next();
2352
2353 Self {
2354 reader,
2355 lookahead,
2356 entity_resolver,
2357 }
2358 }
2359
2360 /// Returns `true` if all events was consumed
2361 const fn is_empty(&self) -> bool {
2362 matches!(self.lookahead, Ok(PayloadEvent::Eof))
2363 }
2364
2365 /// Read next event and put it in lookahead, return the current lookahead
2366 #[inline(always)]
2367 fn next_impl(&mut self) -> Result<PayloadEvent<'i>, DeError> {
2368 replace(&mut self.lookahead, self.reader.next())
2369 }
2370
2371 /// Returns `true` when next event is not a text event in any form.
2372 #[inline(always)]
2373 const fn current_event_is_last_text(&self) -> bool {
2374 // If next event is a text-like event or a DocType (which is
2375 // metadata and invisible to the data model), we should not
2376 // trim trailing spaces — there is more content to drain, and
2377 // any DocType between us and the next text run needs to be
2378 // absorbed so `read_text` does not later see two consecutive
2379 // `DeEvent::Text`. Without DocType here, an input like
2380 // `<a>x<!DOCTYPE y>z</a>` produces two text events for `x`
2381 // and `z`, tripping `unreachable!()` in `read_text`.
2382 !matches!(
2383 self.lookahead,
2384 Ok(PayloadEvent::Text(_)
2385 | PayloadEvent::CData(_)
2386 | PayloadEvent::GeneralRef(_)
2387 | PayloadEvent::DocType(_))
2388 )
2389 }
2390
2391 /// Read all consequent [`Text`] and [`CData`] events until non-text event
2392 /// occurs. Content of all events would be appended to `result` and returned
2393 /// as [`DeEvent::Text`].
2394 ///
2395 /// DocType events that fall between text events are absorbed by the
2396 /// entity resolver and do not break the run — see
2397 /// [`Self::current_event_is_last_text`] for the rationale.
2398 ///
2399 /// [`Text`]: PayloadEvent::Text
2400 /// [`CData`]: PayloadEvent::CData
2401 fn drain_text(&mut self, mut result: Cow<'i, str>) -> Result<DeEvent<'i>, DeError> {
2402 loop {
2403 if self.current_event_is_last_text() {
2404 break;
2405 }
2406
2407 match self.next_impl()? {
2408 PayloadEvent::Text(e) => result
2409 .to_mut()
2410 .push_str(&e.xml_content(self.reader.xml_version())),
2411 PayloadEvent::CData(e) => result
2412 .to_mut()
2413 .push_str(&e.xml_content(self.reader.xml_version())),
2414 PayloadEvent::GeneralRef(e) => self.resolve_reference(result.to_mut(), e)?,
2415 PayloadEvent::DocType(e) => {
2416 self.entity_resolver
2417 .capture(e)
2418 .map_err(|err| DeError::Custom(format!("cannot parse DTD: {}", err)))?;
2419 }
2420
2421 // SAFETY: current_event_is_last_text checks that event is Text, CData, GeneralRef, or DocType
2422 _ => unreachable!(
2423 "Only `Text`, `CData`, `GeneralRef` or `DocType` events can come here"
2424 ),
2425 }
2426 }
2427 Ok(DeEvent::Text(Text::new(result)))
2428 }
2429
2430 /// Return an input-borrowing event.
2431 fn next(&mut self) -> Result<DeEvent<'i>, DeError> {
2432 loop {
2433 return match self.next_impl()? {
2434 PayloadEvent::Start(e) => Ok(DeEvent::Start(e)),
2435 PayloadEvent::End(e) => Ok(DeEvent::End(e)),
2436 PayloadEvent::Text(e) => self.drain_text(e.xml_content(self.reader.xml_version())),
2437 PayloadEvent::CData(e) => self.drain_text(e.xml_content(self.reader.xml_version())),
2438 PayloadEvent::DocType(e) => {
2439 self.entity_resolver
2440 .capture(e)
2441 .map_err(|err| DeError::Custom(format!("cannot parse DTD: {}", err)))?;
2442 continue;
2443 }
2444 PayloadEvent::GeneralRef(e) => {
2445 let mut text = String::new();
2446 self.resolve_reference(&mut text, e)?;
2447 self.drain_text(text.into())
2448 }
2449 PayloadEvent::Eof => Ok(DeEvent::Eof),
2450 };
2451 }
2452 }
2453
2454 fn resolve_reference(&mut self, result: &mut String, event: BytesRef) -> Result<(), DeError> {
2455 let len = event.len();
2456 let reference = event.as_ref();
2457
2458 if let Some(num) = reference.strip_prefix('#') {
2459 let codepoint = parse_number(num).map_err(EscapeError::InvalidCharRef)?;
2460 result.push_str(codepoint.encode_utf8(&mut [0u8; 4]));
2461 return Ok(());
2462 }
2463 if let Some(value) = self.entity_resolver.resolve(reference) {
2464 result.push_str(value);
2465 return Ok(());
2466 }
2467 Err(EscapeError::UnrecognizedEntity(0..len, reference.to_string()).into())
2468 }
2469
2470 #[inline]
2471 fn read_to_end(&mut self, name: QName) -> Result<(), DeError> {
2472 match self.lookahead {
2473 // We pre-read event with the same name that is required to be skipped.
2474 // First call of `read_to_end` will end out pre-read event, the second
2475 // will consume other events
2476 Ok(PayloadEvent::Start(ref e)) if e.name() == name => {
2477 let result1 = self.reader.read_to_end(name);
2478 let result2 = self.reader.read_to_end(name);
2479
2480 // In case of error `next_impl` returns `Eof`
2481 let _ = self.next_impl();
2482 result1?;
2483 result2?;
2484 }
2485 // We pre-read event with the same name that is required to be skipped.
2486 // Because this is end event, we already consume the whole tree, so
2487 // nothing to do, just update lookahead
2488 Ok(PayloadEvent::End(ref e)) if e.name() == name => {
2489 let _ = self.next_impl();
2490 }
2491 Ok(_) => {
2492 let result = self.reader.read_to_end(name);
2493
2494 // In case of error `next_impl` returns `Eof`
2495 let _ = self.next_impl();
2496 result?;
2497 }
2498 // Read next lookahead event, unpack error from the current lookahead
2499 Err(_) => {
2500 self.next_impl()?;
2501 }
2502 }
2503 Ok(())
2504 }
2505}
2506
2507////////////////////////////////////////////////////////////////////////////////////////////////////
2508
2509/// Deserialize an instance of type `T` from a string of XML text.
2510pub fn from_str<'de, T>(s: &'de str) -> Result<T, DeError>
2511where
2512 T: Deserialize<'de>,
2513{
2514 let mut de = Deserializer::from_str(s);
2515 T::deserialize(&mut de)
2516}
2517
2518/// Deserialize from a reader. This method will do internal copies of data
2519/// read from `reader`. If you want have a `&str` input and want to borrow
2520/// as much as possible, use [`from_str`].
2521pub fn from_reader<R, T>(reader: R) -> Result<T, DeError>
2522where
2523 R: BufRead,
2524 T: DeserializeOwned,
2525{
2526 let mut de = Deserializer::from_reader(reader);
2527 T::deserialize(&mut de)
2528}
2529
2530////////////////////////////////////////////////////////////////////////////////////////////////////
2531
2532/// A structure that deserializes XML into Rust values.
2533pub struct Deserializer<'de, R, E: EntityResolver = PredefinedEntityResolver>
2534where
2535 R: XmlRead<'de>,
2536{
2537 /// An XML reader that streams events into this deserializer
2538 reader: XmlReader<'de, R, E>,
2539 /// A buffer to manage namespaces
2540 ns_resolver: NamespaceResolver,
2541
2542 /// When deserializing sequences sometimes we have to skip unwanted events.
2543 /// That events should be stored and then replayed. This is a replay buffer,
2544 /// that streams events while not empty. When it exhausted, events will
2545 /// requested from [`Self::reader`].
2546 #[cfg(feature = "overlapped-lists")]
2547 read: VecDeque<DeEvent<'de>>,
2548 /// When deserializing sequences sometimes we have to skip events, because XML
2549 /// is tolerant to elements order and even if in the XSD order is strictly
2550 /// specified (using `xs:sequence`) most of XML parsers allows order violations.
2551 /// That means, that elements, forming a sequence, could be overlapped with
2552 /// other elements, do not related to that sequence.
2553 ///
2554 /// In order to support this, deserializer will scan events and skip unwanted
2555 /// events, store them here. After call [`Self::start_replay()`] all events
2556 /// moved from this to [`Self::read`].
2557 #[cfg(feature = "overlapped-lists")]
2558 write: VecDeque<DeEvent<'de>>,
2559 /// Maximum number of events that can be skipped when processing sequences
2560 /// that occur out-of-order. This field is used to prevent potential
2561 /// denial-of-service (DoS) attacks which could cause infinite memory
2562 /// consumption when parsing a very large amount of XML into a sequence field.
2563 #[cfg(feature = "overlapped-lists")]
2564 limit: Option<NonZeroUsize>,
2565
2566 #[cfg(not(feature = "overlapped-lists"))]
2567 peek: Option<DeEvent<'de>>,
2568
2569 /// Buffer to store attribute name as a field name exposed to serde consumers
2570 key_buf: String,
2571
2572 /// Current recursion depth (number of nested `ElementMapAccess` and `EnumAccess`
2573 /// instances on the call stack).
2574 depth: usize,
2575 /// Maximum allowed recursion depth. Defaults to 128.
2576 max_depth: usize,
2577}
2578
2579impl<'de, R, E> Deserializer<'de, R, E>
2580where
2581 R: XmlRead<'de>,
2582 E: EntityResolver,
2583{
2584 /// Create an XML deserializer from one of the possible quick_xml input sources.
2585 ///
2586 /// Typically it is more convenient to use one of these methods instead:
2587 ///
2588 /// - [`Deserializer::from_str`]
2589 /// - [`Deserializer::from_reader`]
2590 fn new(reader: R, ns_resolver: NamespaceResolver, entity_resolver: E) -> Self {
2591 Self {
2592 reader: XmlReader::new(reader, entity_resolver),
2593 ns_resolver,
2594
2595 #[cfg(feature = "overlapped-lists")]
2596 read: VecDeque::new(),
2597 #[cfg(feature = "overlapped-lists")]
2598 write: VecDeque::new(),
2599 #[cfg(feature = "overlapped-lists")]
2600 limit: None,
2601
2602 #[cfg(not(feature = "overlapped-lists"))]
2603 peek: None,
2604
2605 key_buf: String::new(),
2606
2607 depth: 0,
2608 max_depth: 128,
2609 }
2610 }
2611
2612 /// Returns `true` if all events was consumed.
2613 pub fn is_empty(&self) -> bool {
2614 #[cfg(feature = "overlapped-lists")]
2615 let event = self.read.front();
2616
2617 #[cfg(not(feature = "overlapped-lists"))]
2618 let event = self.peek.as_ref();
2619
2620 match event {
2621 None | Some(DeEvent::Eof) => self.reader.is_empty(),
2622 _ => false,
2623 }
2624 }
2625
2626 /// Returns the underlying XML reader.
2627 ///
2628 /// ```
2629 /// # use pretty_assertions::assert_eq;
2630 /// use serde::Deserialize;
2631 /// use quick_xml::de::Deserializer;
2632 /// use quick_xml::Reader;
2633 ///
2634 /// #[derive(Deserialize)]
2635 /// struct SomeStruct {
2636 /// field1: String,
2637 /// field2: String,
2638 /// }
2639 ///
2640 /// // Try to deserialize from broken XML
2641 /// let mut de = Deserializer::from_str(
2642 /// "<SomeStruct><field1><field2></SomeStruct>"
2643 /// // 0 ^= 28 ^= 41
2644 /// );
2645 ///
2646 /// let err = SomeStruct::deserialize(&mut de);
2647 /// assert!(err.is_err());
2648 ///
2649 /// let reader: &Reader<_> = de.get_ref().get_ref();
2650 ///
2651 /// assert_eq!(reader.error_position(), 28);
2652 /// assert_eq!(reader.buffer_position(), 41);
2653 /// ```
2654 pub const fn get_ref(&self) -> &R {
2655 &self.reader.reader
2656 }
2657
2658 /// Returns a storage of namespace bindings associated with this deserializer.
2659 #[inline]
2660 pub const fn resolver(&self) -> &NamespaceResolver {
2661 &self.ns_resolver
2662 }
2663
2664 /// Returns a mutable reference to the storage of namespace bindings
2665 /// associated with this deserializer.
2666 ///
2667 /// Useful for configuring the resolver, e.g. to change the
2668 /// [namespace-binding limit](NamespaceResolver::set_max_namespace_bindings).
2669 #[inline]
2670 pub fn resolver_mut(&mut self) -> &mut NamespaceResolver {
2671 &mut self.ns_resolver
2672 }
2673
2674 /// Set the maximum number of events that could be skipped during deserialization
2675 /// of sequences.
2676 ///
2677 /// If `<element>` contains more than specified nested elements, `$text` or
2678 /// CDATA nodes, then [`DeError::TooManyEvents`] will be returned during
2679 /// deserialization of sequence field (any type that uses [`deserialize_seq`]
2680 /// for the deserialization, for example, `Vec<T>`).
2681 ///
2682 /// This method can be used to prevent a [DoS] attack and infinite memory
2683 /// consumption when parsing a very large XML to a sequence field.
2684 ///
2685 /// It is strongly recommended to set limit to some value when you parse data
2686 /// from untrusted sources. You should choose a value that your typical XMLs
2687 /// can have _between_ different elements that corresponds to the same sequence.
2688 ///
2689 /// # Examples
2690 ///
2691 /// Let's imagine, that we deserialize such structure:
2692 /// ```
2693 /// struct List {
2694 /// item: Vec<()>,
2695 /// }
2696 /// ```
2697 ///
2698 /// The XML that we try to parse look like this:
2699 /// ```xml
2700 /// <any-name>
2701 /// <item/>
2702 /// <!-- Bufferization starts at this point -->
2703 /// <another-item>
2704 /// <some-element>with text</some-element>
2705 /// <yet-another-element/>
2706 /// </another-item>
2707 /// <!-- Buffer will be emptied at this point; 7 events were buffered -->
2708 /// <item/>
2709 /// <!-- There is nothing to buffer, because elements follows each other -->
2710 /// <item/>
2711 /// </any-name>
2712 /// ```
2713 ///
2714 /// There, when we deserialize the `item` field, we need to buffer 7 events,
2715 /// before we can deserialize the second `<item/>`:
2716 ///
2717 /// - `<another-item>`
2718 /// - `<some-element>`
2719 /// - `$text(with text)`
2720 /// - `</some-element>`
2721 /// - `<yet-another-element/>` (virtual start event)
2722 /// - `<yet-another-element/>` (virtual end event)
2723 /// - `</another-item>`
2724 ///
2725 /// Note, that `<yet-another-element/>` internally represented as 2 events:
2726 /// one for the start tag and one for the end tag. In the future this can be
2727 /// eliminated, but for now we use [auto-expanding feature] of a reader,
2728 /// because this simplifies deserializer code.
2729 ///
2730 /// [`deserialize_seq`]: serde::Deserializer::deserialize_seq
2731 /// [DoS]: https://en.wikipedia.org/wiki/Denial-of-service_attack
2732 /// [auto-expanding feature]: crate::reader::Config::expand_empty_elements
2733 #[cfg(feature = "overlapped-lists")]
2734 pub fn event_buffer_size(&mut self, limit: Option<NonZeroUsize>) -> &mut Self {
2735 self.limit = limit;
2736 self
2737 }
2738
2739 /// Set the maximum recursion depth for deserialization of nested structures.
2740 ///
2741 /// If the XML nesting exceeds this limit, [`DeError::TooDeeplyNested`] will
2742 /// be returned. The default limit is 128, matching `serde_json`.
2743 ///
2744 /// This method can be used to prevent stack overflow from a [DoS] attack
2745 /// when parsing untrusted XML with deep nesting.
2746 ///
2747 /// # Examples
2748 ///
2749 /// ```
2750 /// # use pretty_assertions::assert_eq;
2751 /// use quick_xml::de::Deserializer;
2752 /// use quick_xml::errors::serialize::DeError;
2753 /// use serde::Deserialize;
2754 ///
2755 /// #[derive(Debug, Deserialize)]
2756 /// struct Nested {
2757 /// inner: Option<Box<Nested>>,
2758 /// }
2759 ///
2760 /// // 3 levels of nesting: <Nested><inner><inner></inner></inner></Nested>
2761 /// let xml = "<Nested><inner><inner></inner></inner></Nested>";
2762 ///
2763 /// // With sufficient limit, deserialization succeeds
2764 /// let mut de = Deserializer::from_str(xml);
2765 /// de.recursion_limit(3);
2766 /// assert!(Nested::deserialize(&mut de).is_ok());
2767 ///
2768 /// // With a low limit, deserialization fails
2769 /// let mut de = Deserializer::from_str(xml);
2770 /// de.recursion_limit(2);
2771 /// assert!(matches!(
2772 /// Nested::deserialize(&mut de),
2773 /// Err(DeError::TooDeeplyNested(2))
2774 /// ));
2775 /// ```
2776 ///
2777 /// [DoS]: https://en.wikipedia.org/wiki/Denial-of-service_attack
2778 pub fn recursion_limit(&mut self, limit: usize) -> &mut Self {
2779 self.max_depth = limit;
2780 self
2781 }
2782
2783 #[cfg(feature = "overlapped-lists")]
2784 fn peek(&mut self) -> Result<&DeEvent<'de>, DeError> {
2785 if self.read.is_empty() {
2786 self.read.push_front(self.reader.next()?);
2787 }
2788 if let Some(event) = self.read.front() {
2789 return Ok(event);
2790 }
2791 // SAFETY: `self.read` was filled in the code above.
2792 // NOTE: with msrv=1.95 we may use push_front_mut
2793 // NOTE: Can be replaced with `unsafe { std::hint::unreachable_unchecked() }`
2794 // if unsafe code will be allowed
2795 unreachable!()
2796 }
2797 #[cfg(not(feature = "overlapped-lists"))]
2798 fn peek(&mut self) -> Result<&DeEvent<'de>, DeError> {
2799 match &mut self.peek {
2800 Some(event) => Ok(event),
2801 empty_peek @ None => Ok(empty_peek.insert(self.reader.next()?)),
2802 }
2803 }
2804
2805 #[cfg(feature = "overlapped-lists")]
2806 fn take_peeked(&mut self) -> Option<DeEvent<'de>> {
2807 self.read.pop_front()
2808 }
2809
2810 #[cfg(not(feature = "overlapped-lists"))]
2811 fn take_peeked(&mut self) -> Option<DeEvent<'de>> {
2812 self.peek.take()
2813 }
2814
2815 fn next_impl(&mut self) -> Result<DeEvent<'de>, DeError> {
2816 // Replay skipped or peeked events
2817 if let Some(e) = self.take_peeked() {
2818 return Ok(e);
2819 }
2820 self.reader.next()
2821 }
2822
2823 fn next(&mut self) -> Result<DeEvent<'de>, DeError> {
2824 match self.next_impl() {
2825 Ok(DeEvent::Start(e)) => {
2826 self.ns_resolver.push(&e)?;
2827 Ok(DeEvent::Start(e))
2828 }
2829 Ok(DeEvent::End(e)) => {
2830 self.ns_resolver.pop();
2831 Ok(DeEvent::End(e))
2832 }
2833 e => e,
2834 }
2835 }
2836
2837 fn skip_whitespaces(&mut self) -> Result<(), DeError> {
2838 loop {
2839 match self.peek()? {
2840 DeEvent::Text(e) if e.is_blank() => {
2841 self.next()?;
2842 }
2843 _ => break,
2844 }
2845 }
2846 Ok(())
2847 }
2848
2849 /// Returns the mark after which all events, skipped by [`Self::skip()`] call,
2850 /// should be replayed after calling [`Self::start_replay()`].
2851 #[cfg(feature = "overlapped-lists")]
2852 #[inline]
2853 #[must_use = "returned checkpoint should be used in `start_replay`"]
2854 fn skip_checkpoint(&self) -> usize {
2855 self.write.len()
2856 }
2857
2858 /// Extracts XML tree of events from and stores them in the skipped events
2859 /// buffer from which they can be retrieved later. You MUST call
2860 /// [`Self::start_replay()`] after calling this to give access to the skipped
2861 /// events and release internal buffers.
2862 #[cfg(feature = "overlapped-lists")]
2863 fn skip(&mut self) -> Result<(), DeError> {
2864 let event = self.next()?;
2865 self.skip_event(event)?;
2866 // Skip all subtree, if we skip a start event
2867 if let Some(DeEvent::Start(e)) = self.write.back() {
2868 let end = e.name().as_ref().as_bytes().to_owned();
2869 let mut depth = 0;
2870 loop {
2871 let event = self.next()?;
2872 match event {
2873 DeEvent::Start(ref e) if e.name().as_ref().as_bytes() == end.as_slice() => {
2874 self.skip_event(event)?;
2875 depth += 1;
2876 }
2877 DeEvent::End(ref e) if e.name().as_ref().as_bytes() == end.as_slice() => {
2878 self.skip_event(event)?;
2879 if depth == 0 {
2880 break;
2881 }
2882 depth -= 1;
2883 }
2884 DeEvent::Eof => {
2885 self.skip_event(event)?;
2886 break;
2887 }
2888 _ => self.skip_event(event)?,
2889 }
2890 }
2891 }
2892 Ok(())
2893 }
2894
2895 #[cfg(feature = "overlapped-lists")]
2896 #[inline]
2897 fn skip_event(&mut self, event: DeEvent<'de>) -> Result<(), DeError> {
2898 if let Some(max) = self.limit {
2899 if self.write.len() >= max.get() {
2900 return Err(DeError::TooManyEvents(max));
2901 }
2902 }
2903 self.write.push_back(event);
2904 Ok(())
2905 }
2906
2907 /// Moves buffered events, skipped after given `checkpoint` from [`Self::write`]
2908 /// skip buffer to [`Self::read`] buffer.
2909 ///
2910 /// After calling this method, [`Self::peek()`] and [`Self::next()`] starts
2911 /// return events that was skipped previously by calling [`Self::skip()`],
2912 /// and only when all that events will be consumed, the deserializer starts
2913 /// to drain events from underlying reader.
2914 ///
2915 /// This method MUST be called if any number of [`Self::skip()`] was called
2916 /// after [`Self::new()`] or `start_replay()` or you'll lost events.
2917 #[cfg(feature = "overlapped-lists")]
2918 fn start_replay(&mut self, checkpoint: usize) {
2919 if checkpoint == 0 {
2920 self.write.append(&mut self.read);
2921 std::mem::swap(&mut self.read, &mut self.write);
2922 } else {
2923 let mut read = self.write.split_off(checkpoint);
2924 read.append(&mut self.read);
2925 self.read = read;
2926 }
2927 }
2928
2929 #[inline]
2930 fn read_string(&mut self) -> Result<Cow<'de, str>, DeError> {
2931 self.read_string_impl(true)
2932 }
2933
2934 /// Consumes consequent [`Text`] and [`CData`] (both a referred below as a _text_)
2935 /// events, merge them into one string. If there are no such events, returns
2936 /// an empty string.
2937 ///
2938 /// If `allow_start` is `false`, then only text events are consumed, for other
2939 /// events an error is returned (see table below).
2940 ///
2941 /// If `allow_start` is `true`, then two or three events are expected:
2942 /// - [`DeEvent::Start`];
2943 /// - _(optional)_ [`DeEvent::Text`] which content is returned;
2944 /// - [`DeEvent::End`]. If text event was missed, an empty string is returned.
2945 ///
2946 /// Corresponding events are consumed.
2947 ///
2948 /// # Handling events
2949 ///
2950 /// The table below shows how events is handled by this method:
2951 ///
2952 /// |Event |XML |Handling
2953 /// |------------------|---------------------------|----------------------------------------
2954 /// |[`DeEvent::Start`]|`<tag>...</tag>` |if `allow_start == true`, result determined by the second table, otherwise emits [`MixedContent("tag")`](DeError::MixedContent)
2955 /// |[`DeEvent::End`] |`</any-tag>` |This is impossible situation, the method will panic if it happens
2956 /// |[`DeEvent::Text`] |`text content` or `<![CDATA[cdata content]]>` (probably mixed)|Returns event content unchanged
2957 /// |[`DeEvent::Eof`] | |Emits [`UnexpectedEof`](DeError::UnexpectedEof)
2958 ///
2959 /// Second event, consumed if [`DeEvent::Start`] was received and `allow_start == true`:
2960 ///
2961 /// |Event |XML |Handling
2962 /// |------------------|---------------------------|----------------------------------------------------------------------------------
2963 /// |[`DeEvent::Start`]|`<any-tag>...</any-tag>` |Emits [`MixedContent("any-tag")`](DeError::MixedContent)
2964 /// |[`DeEvent::End`] |`</tag>` |Returns an empty slice. The reader guarantee that tag will match the open one
2965 /// |[`DeEvent::Text`] |`text content` or `<![CDATA[cdata content]]>` (probably mixed)|Returns event content unchanged, expects the `</tag>` after that
2966 /// |[`DeEvent::Eof`] | |Emits [`InvalidXml(IllFormed(MissingEndTag))`](DeError::InvalidXml)
2967 ///
2968 /// [`Text`]: Event::Text
2969 /// [`CData`]: Event::CData
2970 fn read_string_impl(&mut self, allow_start: bool) -> Result<Cow<'de, str>, DeError> {
2971 match self.next()? {
2972 // Reached by doc tests only: this file, lines 979 and 996
2973 DeEvent::Text(e) => Ok(e.text),
2974 // allow one nested level
2975 // Reached by trivial::{...}::{field, field_nested, field_tag_after, field_tag_before, nested, tag_after, tag_before, wrapped}
2976 DeEvent::Start(e) if allow_start => self.read_text(e.name()),
2977 // TODO: not reached by any tests
2978 DeEvent::Start(e) => Err(DeError::MixedContent(e.name().as_ref().to_owned())),
2979 // SAFETY: The reader is guaranteed that we don't have unmatched tags
2980 // If we here, then our deserializer has a bug
2981 DeEvent::End(e) => unreachable!("{:?}", e),
2982 // Reached by trivial::{empty_doc, only_comment}
2983 DeEvent::Eof => Err(DeError::UnexpectedEof),
2984 }
2985 }
2986 /// Consumes one [`DeEvent::Text`] event and ensures that it is followed by the
2987 /// [`DeEvent::End`] event.
2988 ///
2989 /// # Parameters
2990 /// - `name`: name of a tag opened before reading text. The corresponding end tag
2991 /// should present in input just after the text
2992 fn read_text(&mut self, name: QName) -> Result<Cow<'de, str>, DeError> {
2993 match self.next()? {
2994 DeEvent::Text(e) => match self.next()? {
2995 // The matching tag name is guaranteed by the reader
2996 // Reached by trivial::{...}::{field, wrapped}
2997 DeEvent::End(_) => Ok(e.text),
2998 // SAFETY: Cannot be two consequent Text events, they would be merged into one
2999 DeEvent::Text(_) => unreachable!(),
3000 // Reached by trivial::{...}::{field_tag_after, tag_after}
3001 DeEvent::Start(e) => Err(DeError::MixedContent(e.name().as_ref().to_owned())),
3002 // Reached by struct_::non_closed::elements_child
3003 DeEvent::Eof => Err(Error::missed_end(name).into()),
3004 },
3005 // We can get End event in case of `<tag></tag>` or `<tag/>` input
3006 // Return empty text in that case
3007 // The matching tag name is guaranteed by the reader
3008 // Reached by {...}::xs_list::empty
3009 DeEvent::End(_) => Ok("".into()),
3010 // Reached by trivial::{...}::{field_nested, field_tag_before, nested, tag_before}
3011 DeEvent::Start(s) => Err(DeError::MixedContent(s.name().as_ref().to_owned())),
3012 // Reached by struct_::non_closed::elements_child
3013 DeEvent::Eof => Err(Error::missed_end(name).into()),
3014 }
3015 }
3016
3017 /// Drops all events until event with [name](BytesEnd::name()) `name` won't be
3018 /// dropped. This method should be called after [`Self::next()`]
3019 fn read_to_end(&mut self, name: QName) -> Result<(), DeError> {
3020 let mut depth = 0;
3021 loop {
3022 match self.take_peeked() {
3023 Some(DeEvent::Start(e)) if e.name() == name => {
3024 depth += 1;
3025 }
3026 Some(DeEvent::End(e)) if e.name() == name => {
3027 if depth == 0 {
3028 break;
3029 }
3030 depth -= 1;
3031 }
3032
3033 // Drop all other skipped events
3034 Some(_) => continue,
3035
3036 // If we do not have skipped events, use effective reading that will
3037 // not allocate memory for events
3038 None => {
3039 // We should close all opened tags, because we could buffer
3040 // Start events, but not the corresponding End events. So we
3041 // keep reading events until we exit all nested tags.
3042 // `read_to_end()` will return an error if an Eof was encountered
3043 // preliminary (in case of malformed XML).
3044 //
3045 // <tag><tag></tag></tag>
3046 // ^^^^^^^^^^ - buffered in `self.read`, when `self.read_to_end()` is called, depth = 2
3047 // ^^^^^^ - read by the first call of `self.reader.read_to_end()`
3048 // ^^^^^^ - read by the second call of `self.reader.read_to_end()`
3049 loop {
3050 self.reader.read_to_end(name)?;
3051 if depth == 0 {
3052 break;
3053 }
3054 depth -= 1;
3055 }
3056 break;
3057 }
3058 }
3059 }
3060 // read_to_end will consume closing tag. Because nobody can access to its
3061 // content anymore, we directly pop namespace of the opening tag
3062 self.ns_resolver.pop();
3063 Ok(())
3064 }
3065
3066 /// Determines if `Option` should be deserialized as `Some` or `None`.
3067 ///
3068 /// It handles `xsi:nil` attribute in two places:
3069 /// - on parent element: `<map xsi:nil="true"><opt/></map>`
3070 /// - on checked element: `<map><opt xsi:nil="true"/></map>`
3071 ///
3072 /// According to the [specification], `xsi:nil` controls only ability to (not) have nested
3073 /// elements, but it does not applied to attributes:
3074 ///
3075 /// > 2.7.2 xsi:nil
3076 /// > -------------
3077 /// >
3078 /// > _XML Schema Definition Language: Structures_ introduces a mechanism for signaling that
3079 /// > an element must be accepted as ·valid· when it has no content despite a content type
3080 /// > which does not require or even necessarily allow empty content. An element can be
3081 /// > ·valid· without content if it has the attribute `xsi:nil` with the value `true`.
3082 /// > An element so labeled must be empty, but can carry attributes if permitted by the
3083 /// > corresponding complex type.
3084 ///
3085 /// Due to that we must deserialize all attributes from the `<map>`.
3086 /// To get an access to them we define Rust struct as follow:
3087 ///
3088 /// ```ignore
3089 /// struct MapTag {
3090 /// #[serde(rename = "@attr")]
3091 /// attr: String,
3092 /// // <opt> element
3093 /// opt: Option<String>,
3094 /// }
3095 /// ```
3096 ///
3097 /// `<map attr = "value" xsi:nil="true"/>` should be deserialized as
3098 /// `MapTag { attr: "value", foo: None }`.
3099 ///
3100 /// `<map attr = "value" xsi:nil="true"><foo/></map>` is invalid XML (see the quote from
3101 /// the specification above), but will be deserialized the same.
3102 ///
3103 /// When we at top-level, `parent` is `None` and we handle only the `<opt xsi:nil="..."/>` case.
3104 ///
3105 /// Returns `true` if `visit_some()` should be called and `false` if `visit_none()`.
3106 ///
3107 /// [specification]: https://www.w3.org/TR/xmlschema11-1/#Instance_Document_Constructions
3108 fn deserialize_opt(&mut self, parent_is_nil: Option<bool>) -> Result<bool, DeError> {
3109 // We cannot use result of `peek()` directly because of borrow checker, so it's inlined here
3110 #[cfg(feature = "overlapped-lists")]
3111 let event = {
3112 if self.read.is_empty() {
3113 self.read.push_front(self.reader.next()?);
3114 }
3115 // SAFETY: `self.read` was filled in the code above.
3116 // NOTE: with msrv=1.95 we may use push_front_mut
3117 self.read
3118 .front()
3119 .expect("`self.read` was filled in the code above")
3120 };
3121
3122 #[cfg(not(feature = "overlapped-lists"))]
3123 let event = match &mut self.peek {
3124 Some(event) => event,
3125 empty_peek @ None => empty_peek.insert(self.reader.next()?),
3126 };
3127
3128 Ok(match event {
3129 DeEvent::Text(t) if t.is_empty() => false,
3130 // If we inside the tree, call visit_some for Eof to get an error from the visitor
3131 // (getting Eof means that XML tag is not closed). On top-level Eof is true None
3132 DeEvent::Eof => parent_is_nil.is_some(),
3133 // if the `xsi:nil` attribute is set to true we got a none value
3134 DeEvent::Start(start)
3135 // Because we only peek event here, its namespace bindings not yet processed.
3136 // Temporary push them inside `with` to check the presence of `xsi:nil`
3137 if parent_is_nil.unwrap_or(false) || self.ns_resolver.with(start, |resolver| {
3138 start.attributes().has_nil(resolver)
3139 })? =>
3140 {
3141 let DeEvent::Start(start) = self.next()? else {
3142 unreachable!("Just checked that the next event is a start event")
3143 };
3144 self.read_to_end(start.name())?;
3145 false
3146 }
3147 _ => true,
3148 })
3149 }
3150
3151 /// Method for testing Deserializer implementation. Checks that all events was consumed during
3152 /// deserialization. Panics if the next event will not be [`DeEvent::Eof`].
3153 #[doc(hidden)]
3154 #[track_caller]
3155 pub fn check_eof_reached(&mut self) {
3156 // Deserializer may not consume trailing spaces, that is normal
3157 self.skip_whitespaces().expect("cannot skip whitespaces");
3158 let event = self.peek().expect("cannot peek event");
3159 assert_eq!(
3160 *event,
3161 DeEvent::Eof,
3162 "the whole XML document should be consumed, expected `Eof`",
3163 );
3164 }
3165}
3166
3167impl<'de> Deserializer<'de, SliceReader<'de>> {
3168 /// Create a new deserializer that will borrow data from the specified string.
3169 ///
3170 /// Deserializer created with this method will not resolve custom entities.
3171 #[allow(clippy::should_implement_trait)]
3172 pub fn from_str(source: &'de str) -> Self {
3173 Self::from_str_with_resolver(source, PredefinedEntityResolver)
3174 }
3175
3176 /// Create a new deserializer that will borrow data from the specified preconfigured
3177 /// reader.
3178 ///
3179 /// Deserializer created with this method will not resolve custom entities.
3180 ///
3181 /// Note, that config option [`Config::expand_empty_elements`] will be set to `true`.
3182 ///
3183 /// # Example
3184 ///
3185 /// ```
3186 /// # use pretty_assertions::assert_eq;
3187 /// # use quick_xml::de::Deserializer;
3188 /// # use quick_xml::NsReader;
3189 /// # use serde::Deserialize;
3190 /// #
3191 /// #[derive(Deserialize, PartialEq, Debug)]
3192 /// struct Object<'a> {
3193 /// tag: &'a str,
3194 /// }
3195 ///
3196 /// let mut reader = NsReader::from_str("<xml><tag> test </tag></xml>");
3197 ///
3198 /// let mut de = Deserializer::borrowing(reader.clone());
3199 /// let obj = Object::deserialize(&mut de).unwrap();
3200 /// assert_eq!(obj, Object { tag: " test " });
3201 ///
3202 /// reader.config_mut().trim_text(true);
3203 ///
3204 /// let mut de = Deserializer::borrowing(reader);
3205 /// let obj = Object::deserialize(&mut de).unwrap();
3206 /// assert_eq!(obj, Object { tag: "test" });
3207 /// ```
3208 ///
3209 /// [`Config::expand_empty_elements`]: crate::reader::Config::expand_empty_elements
3210 #[inline]
3211 pub fn borrowing(reader: NsReader<&'de [u8]>) -> Self {
3212 Self::borrowing_with_resolver(reader, PredefinedEntityResolver)
3213 }
3214}
3215
3216impl<'de, E> Deserializer<'de, SliceReader<'de>, E>
3217where
3218 E: EntityResolver,
3219{
3220 /// Create a new deserializer that will borrow data from the specified string
3221 /// and use the specified entity resolver.
3222 pub fn from_str_with_resolver(source: &'de str, entity_resolver: E) -> Self {
3223 Self::borrowing_with_resolver(NsReader::from_str(source), entity_resolver)
3224 }
3225
3226 /// Create a new deserializer that will borrow data from the specified preconfigured
3227 /// reader and use the specified entity resolver.
3228 ///
3229 /// Note, that config option [`Config::expand_empty_elements`] will be set to `true`.
3230 ///
3231 /// [`Config::expand_empty_elements`]: crate::reader::Config::expand_empty_elements
3232 pub fn borrowing_with_resolver(reader: NsReader<&'de [u8]>, entity_resolver: E) -> Self {
3233 let NsReader {
3234 mut reader,
3235 mut ns_resolver,
3236 pending_pop,
3237 } = reader;
3238 let config = reader.config_mut();
3239 config.expand_empty_elements = true;
3240
3241 if pending_pop {
3242 ns_resolver.pop();
3243 }
3244
3245 Self::new(
3246 SliceReader {
3247 reader,
3248 version: XmlVersion::Implicit1_0,
3249 },
3250 ns_resolver,
3251 entity_resolver,
3252 )
3253 }
3254}
3255
3256impl<'de, R> Deserializer<'de, IoReader<R>>
3257where
3258 R: BufRead,
3259{
3260 /// Create a new deserializer that will copy data from the specified reader
3261 /// into internal buffer.
3262 ///
3263 /// If you already have a string use [`Self::from_str`] instead, because it
3264 /// will borrow instead of copy. If you have `&[u8]` which is known to represent
3265 /// UTF-8, you can decode it first before using [`from_str`].
3266 ///
3267 /// Deserializer created with this method will not resolve custom entities.
3268 pub fn from_reader(reader: R) -> Self {
3269 Self::with_resolver(reader, PredefinedEntityResolver)
3270 }
3271
3272 /// Create a new deserializer that will copy data from the specified preconfigured
3273 /// reader into internal buffer.
3274 ///
3275 /// Deserializer created with this method will not resolve custom entities.
3276 ///
3277 /// Note, that config option [`Config::expand_empty_elements`] will be set to `true`.
3278 ///
3279 /// # Example
3280 ///
3281 /// ```
3282 /// # use pretty_assertions::assert_eq;
3283 /// # use quick_xml::de::Deserializer;
3284 /// # use quick_xml::NsReader;
3285 /// # use serde::Deserialize;
3286 /// #
3287 /// #[derive(Deserialize, PartialEq, Debug)]
3288 /// struct Object {
3289 /// tag: String,
3290 /// }
3291 ///
3292 /// let mut reader = NsReader::from_str("<xml><tag> test </tag></xml>");
3293 ///
3294 /// let mut de = Deserializer::buffering(reader.clone());
3295 /// let obj = Object::deserialize(&mut de).unwrap();
3296 /// assert_eq!(obj, Object { tag: " test ".to_string() });
3297 ///
3298 /// reader.config_mut().trim_text(true);
3299 ///
3300 /// let mut de = Deserializer::buffering(reader);
3301 /// let obj = Object::deserialize(&mut de).unwrap();
3302 /// assert_eq!(obj, Object { tag: "test".to_string() });
3303 /// ```
3304 ///
3305 /// [`Config::expand_empty_elements`]: crate::reader::Config::expand_empty_elements
3306 #[inline]
3307 pub fn buffering(reader: NsReader<R>) -> Self {
3308 Self::buffering_with_resolver(reader, PredefinedEntityResolver)
3309 }
3310}
3311
3312impl<'de, R, E> Deserializer<'de, IoReader<R>, E>
3313where
3314 R: BufRead,
3315 E: EntityResolver,
3316{
3317 /// Create a new deserializer that will copy data from the specified reader
3318 /// into internal buffer and use the specified entity resolver.
3319 ///
3320 /// If you already have a string use [`Self::from_str`] instead, because it
3321 /// will borrow instead of copy. If you have `&[u8]` which is known to represent
3322 /// UTF-8, you can decode it first before using [`from_str`].
3323 pub fn with_resolver(reader: R, entity_resolver: E) -> Self {
3324 let mut reader = Reader::from_reader(reader);
3325 let config = reader.config_mut();
3326 config.expand_empty_elements = true;
3327
3328 Self::new(
3329 IoReader {
3330 reader,
3331 buf: Vec::new(),
3332 version: XmlVersion::Implicit1_0,
3333 },
3334 NamespaceResolver::default(),
3335 entity_resolver,
3336 )
3337 }
3338
3339 /// Create new deserializer that will copy data from the specified preconfigured reader
3340 /// into internal buffer and use the specified entity resolver.
3341 ///
3342 /// Note, that config option [`Config::expand_empty_elements`] will be set to `true`.
3343 ///
3344 /// [`Config::expand_empty_elements`]: crate::reader::Config::expand_empty_elements
3345 pub fn buffering_with_resolver(reader: NsReader<R>, entity_resolver: E) -> Self {
3346 let NsReader {
3347 mut reader,
3348 mut ns_resolver,
3349 pending_pop,
3350 } = reader;
3351 let config = reader.config_mut();
3352 config.expand_empty_elements = true;
3353
3354 if pending_pop {
3355 ns_resolver.pop();
3356 }
3357
3358 Self::new(
3359 IoReader {
3360 reader,
3361 buf: Vec::new(),
3362 version: XmlVersion::Implicit1_0,
3363 },
3364 ns_resolver,
3365 entity_resolver,
3366 )
3367 }
3368}
3369
3370impl<'de, R, E> de::Deserializer<'de> for &mut Deserializer<'de, R, E>
3371where
3372 R: XmlRead<'de>,
3373 E: EntityResolver,
3374{
3375 type Error = DeError;
3376
3377 deserialize_primitives!();
3378
3379 fn deserialize_struct<V>(
3380 self,
3381 _name: &'static str,
3382 fields: &'static [&'static str],
3383 visitor: V,
3384 ) -> Result<V::Value, DeError>
3385 where
3386 V: Visitor<'de>,
3387 {
3388 // When document is pretty-printed there could be whitespaces before the root element
3389 self.skip_whitespaces()?;
3390 match self.next()? {
3391 DeEvent::Start(e) => visitor.visit_map(ElementMapAccess::new(self, e, fields)?),
3392 // SAFETY: The reader is guaranteed that we don't have unmatched tags
3393 // If we here, then our deserializer has a bug
3394 DeEvent::End(e) => unreachable!("{:?}", e),
3395 // Deserializer methods are only hints, if deserializer could not satisfy
3396 // request, it should return the data that it has. It is responsibility
3397 // of a Visitor to return an error if it does not understand the data
3398 DeEvent::Text(e) => match e.text {
3399 Cow::Borrowed(s) => visitor.visit_borrowed_str(s),
3400 Cow::Owned(s) => visitor.visit_string(s),
3401 },
3402 DeEvent::Eof => Err(DeError::UnexpectedEof),
3403 }
3404 }
3405
3406 /// Unit represented in XML as a `xs:element` or text/CDATA content.
3407 /// Any content inside `xs:element` is ignored and skipped.
3408 ///
3409 /// Produces unit struct from any of following inputs:
3410 /// - any `<tag ...>...</tag>`
3411 /// - any `<tag .../>`
3412 /// - any consequent text / CDATA content (can consist of several parts
3413 /// delimited by comments and processing instructions)
3414 ///
3415 /// # Events handling
3416 ///
3417 /// |Event |XML |Handling
3418 /// |------------------|---------------------------|-------------------------------------------
3419 /// |[`DeEvent::Start`]|`<tag>...</tag>` |Calls `visitor.visit_unit()`, consumes all events up to and including corresponding `End` event
3420 /// |[`DeEvent::End`] |`</tag>` |This is impossible situation, the method will panic if it happens
3421 /// |[`DeEvent::Text`] |`text content` or `<![CDATA[cdata content]]>` (probably mixed)|Calls `visitor.visit_unit()`. The content is ignored
3422 /// |[`DeEvent::Eof`] | |Emits [`UnexpectedEof`](DeError::UnexpectedEof)
3423 fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, DeError>
3424 where
3425 V: Visitor<'de>,
3426 {
3427 match self.next()? {
3428 DeEvent::Start(s) => {
3429 self.read_to_end(s.name())?;
3430 visitor.visit_unit()
3431 }
3432 DeEvent::Text(_) => visitor.visit_unit(),
3433 // SAFETY: The reader is guaranteed that we don't have unmatched tags
3434 // If we here, then our deserializer has a bug
3435 DeEvent::End(e) => unreachable!("{:?}", e),
3436 DeEvent::Eof => Err(DeError::UnexpectedEof),
3437 }
3438 }
3439
3440 /// Forwards deserialization of the inner type. Always calls [`Visitor::visit_newtype_struct`]
3441 /// with the same deserializer.
3442 fn deserialize_newtype_struct<V>(
3443 self,
3444 _name: &'static str,
3445 visitor: V,
3446 ) -> Result<V::Value, DeError>
3447 where
3448 V: Visitor<'de>,
3449 {
3450 visitor.visit_newtype_struct(self)
3451 }
3452
3453 fn deserialize_enum<V>(
3454 self,
3455 _name: &'static str,
3456 _variants: &'static [&'static str],
3457 visitor: V,
3458 ) -> Result<V::Value, DeError>
3459 where
3460 V: Visitor<'de>,
3461 {
3462 // When document is pretty-printed there could be whitespaces before the root element
3463 // which represents the enum variant
3464 // Checked by `top_level::list_of_enum` test in serde-de-seq
3465 self.skip_whitespaces()?;
3466 if self.depth >= self.max_depth {
3467 return Err(DeError::TooDeeplyNested(self.max_depth));
3468 }
3469 self.depth += 1;
3470 let result = visitor.visit_enum(var::EnumAccess::new(self));
3471 self.depth -= 1;
3472 result
3473 }
3474
3475 fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, DeError>
3476 where
3477 V: Visitor<'de>,
3478 {
3479 visitor.visit_seq(self)
3480 }
3481
3482 fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, DeError>
3483 where
3484 V: Visitor<'de>,
3485 {
3486 if self.deserialize_opt(None)? {
3487 visitor.visit_some(self)
3488 } else {
3489 visitor.visit_none()
3490 }
3491 }
3492
3493 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, DeError>
3494 where
3495 V: Visitor<'de>,
3496 {
3497 match self.peek()? {
3498 DeEvent::Text(_) => self.deserialize_str(visitor),
3499 _ => self.deserialize_map(visitor),
3500 }
3501 }
3502}
3503
3504/// An accessor to sequence elements forming a value for top-level sequence of XML
3505/// elements.
3506///
3507/// Technically, multiple top-level elements violates XML rule of only one top-level
3508/// element, but we consider this as several concatenated XML documents.
3509impl<'de, R, E> SeqAccess<'de> for &mut Deserializer<'de, R, E>
3510where
3511 R: XmlRead<'de>,
3512 E: EntityResolver,
3513{
3514 type Error = DeError;
3515
3516 fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
3517 where
3518 T: DeserializeSeed<'de>,
3519 {
3520 // When document is pretty-printed there could be whitespaces before, between
3521 // and after root elements. We cannot defer decision if we need to skip spaces
3522 // or not: if we have a sequence of type that does not accept blank text, it
3523 // will need to return something and it can return only error. For example,
3524 // it can be enum without `$text` variant
3525 // Checked by `top_level::list_of_enum` test in serde-de-seq
3526 self.skip_whitespaces()?;
3527 match self.peek()? {
3528 DeEvent::Eof => Ok(None),
3529
3530 // Start(tag), End(tag), Text
3531 _ => seed.deserialize(&mut **self).map(Some),
3532 }
3533 }
3534}
3535
3536impl<'de, R, E> IntoDeserializer<'de, DeError> for &mut Deserializer<'de, R, E>
3537where
3538 R: XmlRead<'de>,
3539 E: EntityResolver,
3540{
3541 type Deserializer = Self;
3542
3543 #[inline]
3544 fn into_deserializer(self) -> Self {
3545 self
3546 }
3547}
3548
3549////////////////////////////////////////////////////////////////////////////////////////////////////
3550
3551/// Converts raw reader's event into a payload event.
3552/// Returns `None`, if event should be skipped.
3553#[inline(always)]
3554fn skip_uninterested<'a>(event: Event<'a>) -> Option<PayloadEvent<'a>> {
3555 let event = match event {
3556 Event::DocType(e) => PayloadEvent::DocType(e),
3557 Event::Start(e) => PayloadEvent::Start(e),
3558 Event::End(e) => PayloadEvent::End(e),
3559 Event::Eof => PayloadEvent::Eof,
3560
3561 // Do not trim next text event after Text, CDATA or reference event
3562 Event::CData(e) => PayloadEvent::CData(e),
3563 Event::Text(e) => PayloadEvent::Text(e),
3564 Event::GeneralRef(e) => PayloadEvent::GeneralRef(e),
3565
3566 _ => return None,
3567 };
3568 Some(event)
3569}
3570
3571////////////////////////////////////////////////////////////////////////////////////////////////////
3572
3573/// Trait used by the deserializer for iterating over input. This is manually
3574/// "specialized" for iterating over `&[u8]`.
3575///
3576/// You do not need to implement this trait, it is needed to abstract from
3577/// [borrowing](SliceReader) and [copying](IoReader) data sources and reuse code in
3578/// deserializer
3579pub trait XmlRead<'i> {
3580 /// Return an input-borrowing event.
3581 fn next(&mut self) -> Result<PayloadEvent<'i>, DeError>;
3582
3583 /// Skips until end element is found. Unlike `next()` it will not allocate
3584 /// when it cannot satisfy the lifetime.
3585 fn read_to_end(&mut self, name: QName) -> Result<(), DeError>;
3586
3587 /// Return an XML version of the source.
3588 fn xml_version(&self) -> XmlVersion;
3589}
3590
3591/// XML input source that reads from a std::io input stream.
3592///
3593/// You cannot create it, it is created automatically when you call
3594/// [`Deserializer::from_reader`]
3595pub struct IoReader<R: BufRead> {
3596 reader: Reader<R>,
3597 buf: Vec<u8>,
3598 version: XmlVersion,
3599}
3600
3601impl<R: BufRead> IoReader<R> {
3602 /// Returns the underlying XML reader.
3603 ///
3604 /// ```
3605 /// # use pretty_assertions::assert_eq;
3606 /// use serde::Deserialize;
3607 /// use std::io::Cursor;
3608 /// use quick_xml::de::Deserializer;
3609 /// use quick_xml::Reader;
3610 ///
3611 /// #[derive(Deserialize)]
3612 /// struct SomeStruct {
3613 /// field1: String,
3614 /// field2: String,
3615 /// }
3616 ///
3617 /// // Try to deserialize from broken XML
3618 /// let mut de = Deserializer::from_reader(Cursor::new(
3619 /// "<SomeStruct><field1><field2></SomeStruct>"
3620 /// // 0 ^= 28 ^= 41
3621 /// ));
3622 ///
3623 /// let err = SomeStruct::deserialize(&mut de);
3624 /// assert!(err.is_err());
3625 ///
3626 /// let reader: &Reader<Cursor<&str>> = de.get_ref().get_ref();
3627 ///
3628 /// assert_eq!(reader.error_position(), 28);
3629 /// assert_eq!(reader.buffer_position(), 41);
3630 /// ```
3631 pub const fn get_ref(&self) -> &Reader<R> {
3632 &self.reader
3633 }
3634}
3635
3636impl<'i, R: BufRead> XmlRead<'i> for IoReader<R> {
3637 fn next(&mut self) -> Result<PayloadEvent<'static>, DeError> {
3638 loop {
3639 self.buf.clear();
3640
3641 let event = self.reader.read_event_into(&mut self.buf)?;
3642 if let Event::Decl(e) = &event {
3643 self.version = e.xml_version()?;
3644 }
3645 if let Some(event) = skip_uninterested(event) {
3646 return Ok(event.into_owned());
3647 }
3648 }
3649 }
3650
3651 fn read_to_end(&mut self, name: QName) -> Result<(), DeError> {
3652 match self.reader.read_to_end_into(name, &mut self.buf) {
3653 Err(e) => Err(e.into()),
3654 Ok(_) => Ok(()),
3655 }
3656 }
3657
3658 #[inline]
3659 fn xml_version(&self) -> XmlVersion {
3660 self.version
3661 }
3662}
3663
3664/// XML input source that reads from a slice of bytes and can borrow from it.
3665///
3666/// You cannot create it, it is created automatically when you call
3667/// [`Deserializer::from_str`].
3668pub struct SliceReader<'de> {
3669 reader: Reader<&'de [u8]>,
3670 version: XmlVersion,
3671}
3672
3673impl<'de> SliceReader<'de> {
3674 /// Returns the underlying XML reader.
3675 ///
3676 /// ```
3677 /// # use pretty_assertions::assert_eq;
3678 /// use serde::Deserialize;
3679 /// use quick_xml::de::Deserializer;
3680 /// use quick_xml::Reader;
3681 ///
3682 /// #[derive(Deserialize)]
3683 /// struct SomeStruct {
3684 /// field1: String,
3685 /// field2: String,
3686 /// }
3687 ///
3688 /// // Try to deserialize from broken XML
3689 /// let mut de = Deserializer::from_str(
3690 /// "<SomeStruct><field1><field2></SomeStruct>"
3691 /// // 0 ^= 28 ^= 41
3692 /// );
3693 ///
3694 /// let err = SomeStruct::deserialize(&mut de);
3695 /// assert!(err.is_err());
3696 ///
3697 /// let reader: &Reader<&[u8]> = de.get_ref().get_ref();
3698 ///
3699 /// assert_eq!(reader.error_position(), 28);
3700 /// assert_eq!(reader.buffer_position(), 41);
3701 /// ```
3702 pub const fn get_ref(&self) -> &Reader<&'de [u8]> {
3703 &self.reader
3704 }
3705}
3706
3707impl<'de> XmlRead<'de> for SliceReader<'de> {
3708 fn next(&mut self) -> Result<PayloadEvent<'de>, DeError> {
3709 loop {
3710 let event = self.reader.read_event()?;
3711 if let Event::Decl(e) = &event {
3712 self.version = e.xml_version()?;
3713 }
3714 if let Some(event) = skip_uninterested(event) {
3715 return Ok(event);
3716 }
3717 }
3718 }
3719
3720 fn read_to_end(&mut self, name: QName) -> Result<(), DeError> {
3721 match self.reader.read_to_end(name) {
3722 Err(e) => Err(e.into()),
3723 Ok(_) => Ok(()),
3724 }
3725 }
3726
3727 #[inline]
3728 fn xml_version(&self) -> XmlVersion {
3729 self.version
3730 }
3731}
3732
3733#[cfg(test)]
3734mod tests {
3735 use super::*;
3736 use crate::errors::IllFormedError;
3737 use pretty_assertions::assert_eq;
3738
3739 fn make_de<'de>(source: &'de str) -> Deserializer<'de, SliceReader<'de>> {
3740 dbg!(source);
3741 Deserializer::from_str(source)
3742 }
3743
3744 #[cfg(feature = "overlapped-lists")]
3745 mod skip {
3746 use super::*;
3747 use crate::de::DeEvent::*;
3748 use crate::events::BytesEnd;
3749 use pretty_assertions::assert_eq;
3750
3751 /// Checks that `peek()` and `read()` behaves correctly after `skip()`
3752 #[test]
3753 fn read_and_peek() {
3754 let mut de = make_de(
3755 "\
3756 <root>\
3757 <inner>\
3758 text\
3759 <inner/>\
3760 </inner>\
3761 <next/>\
3762 <target/>\
3763 </root>\
3764 ",
3765 );
3766
3767 // Initial conditions - both are empty
3768 assert_eq!(de.read, vec![]);
3769 assert_eq!(de.write, vec![]);
3770
3771 assert_eq!(de.next().unwrap(), Start(BytesStart::new("root")));
3772 assert_eq!(de.peek().unwrap(), &Start(BytesStart::new("inner")));
3773
3774 // Mark that start_replay() should begin replay from this point
3775 let checkpoint = de.skip_checkpoint();
3776 assert_eq!(checkpoint, 0);
3777
3778 // Should skip first <inner> tree
3779 de.skip().unwrap();
3780 assert_eq!(de.read, vec![]);
3781 assert_eq!(
3782 de.write,
3783 vec![
3784 Start(BytesStart::new("inner")),
3785 Text("text".into()),
3786 Start(BytesStart::new("inner")),
3787 End(BytesEnd::new("inner")),
3788 End(BytesEnd::new("inner")),
3789 ]
3790 );
3791
3792 // Consume <next/>. Now unconsumed XML looks like:
3793 //
3794 // <inner>
3795 // text
3796 // <inner/>
3797 // </inner>
3798 // <target/>
3799 // </root>
3800 assert_eq!(de.next().unwrap(), Start(BytesStart::new("next")));
3801 assert_eq!(de.next().unwrap(), End(BytesEnd::new("next")));
3802
3803 // We finish writing. Next call to `next()` should start replay that messages:
3804 //
3805 // <inner>
3806 // text
3807 // <inner/>
3808 // </inner>
3809 //
3810 // and after that stream that messages:
3811 //
3812 // <target/>
3813 // </root>
3814 de.start_replay(checkpoint);
3815 assert_eq!(
3816 de.read,
3817 vec![
3818 Start(BytesStart::new("inner")),
3819 Text("text".into()),
3820 Start(BytesStart::new("inner")),
3821 End(BytesEnd::new("inner")),
3822 End(BytesEnd::new("inner")),
3823 ]
3824 );
3825 assert_eq!(de.write, vec![]);
3826 assert_eq!(de.next().unwrap(), Start(BytesStart::new("inner")));
3827
3828 // Mark that start_replay() should begin replay from this point
3829 let checkpoint = de.skip_checkpoint();
3830 assert_eq!(checkpoint, 0);
3831
3832 // Skip `$text` node and consume <inner/> after it
3833 de.skip().unwrap();
3834 assert_eq!(
3835 de.read,
3836 vec![
3837 Start(BytesStart::new("inner")),
3838 End(BytesEnd::new("inner")),
3839 End(BytesEnd::new("inner")),
3840 ]
3841 );
3842 assert_eq!(
3843 de.write,
3844 vec![
3845 // This comment here to keep the same formatting of both arrays
3846 // otherwise rustfmt suggest one-line it
3847 Text("text".into()),
3848 ]
3849 );
3850
3851 assert_eq!(de.next().unwrap(), Start(BytesStart::new("inner")));
3852 assert_eq!(de.next().unwrap(), End(BytesEnd::new("inner")));
3853
3854 // We finish writing. Next call to `next()` should start replay messages:
3855 //
3856 // text
3857 // </inner>
3858 //
3859 // and after that stream that messages:
3860 //
3861 // <target/>
3862 // </root>
3863 de.start_replay(checkpoint);
3864 assert_eq!(
3865 de.read,
3866 vec![
3867 // This comment here to keep the same formatting as others
3868 // otherwise rustfmt suggest one-line it
3869 Text("text".into()),
3870 End(BytesEnd::new("inner")),
3871 ]
3872 );
3873 assert_eq!(de.write, vec![]);
3874 assert_eq!(de.next().unwrap(), Text("text".into()));
3875 assert_eq!(de.next().unwrap(), End(BytesEnd::new("inner")));
3876 assert_eq!(de.next().unwrap(), Start(BytesStart::new("target")));
3877 assert_eq!(de.next().unwrap(), End(BytesEnd::new("target")));
3878 assert_eq!(de.next().unwrap(), End(BytesEnd::new("root")));
3879 assert_eq!(de.next().unwrap(), Eof);
3880 }
3881
3882 /// Checks that `read_to_end()` behaves correctly after `skip()`
3883 #[test]
3884 fn read_to_end() {
3885 let mut de = make_de(
3886 "\
3887 <root>\
3888 <skip>\
3889 text\
3890 <skip/>\
3891 </skip>\
3892 <target>\
3893 <target/>\
3894 </target>\
3895 </root>\
3896 ",
3897 );
3898
3899 // Initial conditions - both are empty
3900 assert_eq!(de.read, vec![]);
3901 assert_eq!(de.write, vec![]);
3902
3903 assert_eq!(de.next().unwrap(), Start(BytesStart::new("root")));
3904
3905 // Mark that start_replay() should begin replay from this point
3906 let checkpoint = de.skip_checkpoint();
3907 assert_eq!(checkpoint, 0);
3908
3909 // Skip the <skip> tree
3910 de.skip().unwrap();
3911 assert_eq!(de.read, vec![]);
3912 assert_eq!(
3913 de.write,
3914 vec![
3915 Start(BytesStart::new("skip")),
3916 Text("text".into()),
3917 Start(BytesStart::new("skip")),
3918 End(BytesEnd::new("skip")),
3919 End(BytesEnd::new("skip")),
3920 ]
3921 );
3922
3923 // Drop all events that represents <target> tree. Now unconsumed XML looks like:
3924 //
3925 // <skip>
3926 // text
3927 // <skip/>
3928 // </skip>
3929 // </root>
3930 assert_eq!(de.next().unwrap(), Start(BytesStart::new("target")));
3931 de.read_to_end(QName("target")).unwrap();
3932 assert_eq!(de.read, vec![]);
3933 assert_eq!(
3934 de.write,
3935 vec![
3936 Start(BytesStart::new("skip")),
3937 Text("text".into()),
3938 Start(BytesStart::new("skip")),
3939 End(BytesEnd::new("skip")),
3940 End(BytesEnd::new("skip")),
3941 ]
3942 );
3943
3944 // We finish writing. Next call to `next()` should start replay that messages:
3945 //
3946 // <skip>
3947 // text
3948 // <skip/>
3949 // </skip>
3950 //
3951 // and after that stream that messages:
3952 //
3953 // </root>
3954 de.start_replay(checkpoint);
3955 assert_eq!(
3956 de.read,
3957 vec![
3958 Start(BytesStart::new("skip")),
3959 Text("text".into()),
3960 Start(BytesStart::new("skip")),
3961 End(BytesEnd::new("skip")),
3962 End(BytesEnd::new("skip")),
3963 ]
3964 );
3965 assert_eq!(de.write, vec![]);
3966
3967 assert_eq!(de.next().unwrap(), Start(BytesStart::new("skip")));
3968 de.read_to_end(QName("skip")).unwrap();
3969
3970 assert_eq!(de.next().unwrap(), End(BytesEnd::new("root")));
3971 assert_eq!(de.next().unwrap(), Eof);
3972 }
3973
3974 /// Checks that replay replayes only part of events
3975 /// Test for https://github.com/tafia/quick-xml/issues/435
3976 #[test]
3977 fn partial_replay() {
3978 let mut de = make_de(
3979 "\
3980 <root>\
3981 <skipped-1/>\
3982 <skipped-2/>\
3983 <inner>\
3984 <skipped-3/>\
3985 <skipped-4/>\
3986 <target-2/>\
3987 </inner>\
3988 <target-1/>\
3989 </root>\
3990 ",
3991 );
3992
3993 // Initial conditions - both are empty
3994 assert_eq!(de.read, vec![]);
3995 assert_eq!(de.write, vec![]);
3996
3997 assert_eq!(de.next().unwrap(), Start(BytesStart::new("root")));
3998
3999 // start_replay() should start replay from this point
4000 let checkpoint1 = de.skip_checkpoint();
4001 assert_eq!(checkpoint1, 0);
4002
4003 // Should skip first and second <skipped-N/> elements
4004 de.skip().unwrap(); // skipped-1
4005 de.skip().unwrap(); // skipped-2
4006 assert_eq!(de.read, vec![]);
4007 assert_eq!(
4008 de.write,
4009 vec![
4010 Start(BytesStart::new("skipped-1")),
4011 End(BytesEnd::new("skipped-1")),
4012 Start(BytesStart::new("skipped-2")),
4013 End(BytesEnd::new("skipped-2")),
4014 ]
4015 );
4016
4017 ////////////////////////////////////////////////////////////////////////////////////////
4018
4019 assert_eq!(de.next().unwrap(), Start(BytesStart::new("inner")));
4020 assert_eq!(de.peek().unwrap(), &Start(BytesStart::new("skipped-3")));
4021 assert_eq!(
4022 de.read,
4023 vec![
4024 // This comment here to keep the same formatting of both arrays
4025 // otherwise rustfmt suggest one-line it
4026 Start(BytesStart::new("skipped-3")),
4027 ]
4028 );
4029 assert_eq!(
4030 de.write,
4031 vec![
4032 Start(BytesStart::new("skipped-1")),
4033 End(BytesEnd::new("skipped-1")),
4034 Start(BytesStart::new("skipped-2")),
4035 End(BytesEnd::new("skipped-2")),
4036 ]
4037 );
4038
4039 // start_replay() should start replay from this point
4040 let checkpoint2 = de.skip_checkpoint();
4041 assert_eq!(checkpoint2, 4);
4042
4043 // Should skip third and forth <skipped-N/> elements
4044 de.skip().unwrap(); // skipped-3
4045 de.skip().unwrap(); // skipped-4
4046 assert_eq!(de.read, vec![]);
4047 assert_eq!(
4048 de.write,
4049 vec![
4050 // checkpoint 1
4051 Start(BytesStart::new("skipped-1")),
4052 End(BytesEnd::new("skipped-1")),
4053 Start(BytesStart::new("skipped-2")),
4054 End(BytesEnd::new("skipped-2")),
4055 // checkpoint 2
4056 Start(BytesStart::new("skipped-3")),
4057 End(BytesEnd::new("skipped-3")),
4058 Start(BytesStart::new("skipped-4")),
4059 End(BytesEnd::new("skipped-4")),
4060 ]
4061 );
4062 assert_eq!(de.next().unwrap(), Start(BytesStart::new("target-2")));
4063 assert_eq!(de.next().unwrap(), End(BytesEnd::new("target-2")));
4064 assert_eq!(de.peek().unwrap(), &End(BytesEnd::new("inner")));
4065 assert_eq!(
4066 de.read,
4067 vec![
4068 // This comment here to keep the same formatting of both arrays
4069 // otherwise rustfmt suggest one-line it
4070 End(BytesEnd::new("inner")),
4071 ]
4072 );
4073 assert_eq!(
4074 de.write,
4075 vec![
4076 // checkpoint 1
4077 Start(BytesStart::new("skipped-1")),
4078 End(BytesEnd::new("skipped-1")),
4079 Start(BytesStart::new("skipped-2")),
4080 End(BytesEnd::new("skipped-2")),
4081 // checkpoint 2
4082 Start(BytesStart::new("skipped-3")),
4083 End(BytesEnd::new("skipped-3")),
4084 Start(BytesStart::new("skipped-4")),
4085 End(BytesEnd::new("skipped-4")),
4086 ]
4087 );
4088
4089 // Start replay events from checkpoint 2
4090 de.start_replay(checkpoint2);
4091 assert_eq!(
4092 de.read,
4093 vec![
4094 Start(BytesStart::new("skipped-3")),
4095 End(BytesEnd::new("skipped-3")),
4096 Start(BytesStart::new("skipped-4")),
4097 End(BytesEnd::new("skipped-4")),
4098 End(BytesEnd::new("inner")),
4099 ]
4100 );
4101 assert_eq!(
4102 de.write,
4103 vec![
4104 Start(BytesStart::new("skipped-1")),
4105 End(BytesEnd::new("skipped-1")),
4106 Start(BytesStart::new("skipped-2")),
4107 End(BytesEnd::new("skipped-2")),
4108 ]
4109 );
4110
4111 // Replayed events
4112 assert_eq!(de.next().unwrap(), Start(BytesStart::new("skipped-3")));
4113 assert_eq!(de.next().unwrap(), End(BytesEnd::new("skipped-3")));
4114 assert_eq!(de.next().unwrap(), Start(BytesStart::new("skipped-4")));
4115 assert_eq!(de.next().unwrap(), End(BytesEnd::new("skipped-4")));
4116
4117 assert_eq!(de.next().unwrap(), End(BytesEnd::new("inner")));
4118 assert_eq!(de.read, vec![]);
4119 assert_eq!(
4120 de.write,
4121 vec![
4122 Start(BytesStart::new("skipped-1")),
4123 End(BytesEnd::new("skipped-1")),
4124 Start(BytesStart::new("skipped-2")),
4125 End(BytesEnd::new("skipped-2")),
4126 ]
4127 );
4128
4129 ////////////////////////////////////////////////////////////////////////////////////////
4130
4131 // New events
4132 assert_eq!(de.next().unwrap(), Start(BytesStart::new("target-1")));
4133 assert_eq!(de.next().unwrap(), End(BytesEnd::new("target-1")));
4134
4135 assert_eq!(de.read, vec![]);
4136 assert_eq!(
4137 de.write,
4138 vec![
4139 Start(BytesStart::new("skipped-1")),
4140 End(BytesEnd::new("skipped-1")),
4141 Start(BytesStart::new("skipped-2")),
4142 End(BytesEnd::new("skipped-2")),
4143 ]
4144 );
4145
4146 // Start replay events from checkpoint 1
4147 de.start_replay(checkpoint1);
4148 assert_eq!(
4149 de.read,
4150 vec![
4151 Start(BytesStart::new("skipped-1")),
4152 End(BytesEnd::new("skipped-1")),
4153 Start(BytesStart::new("skipped-2")),
4154 End(BytesEnd::new("skipped-2")),
4155 ]
4156 );
4157 assert_eq!(de.write, vec![]);
4158
4159 // Replayed events
4160 assert_eq!(de.next().unwrap(), Start(BytesStart::new("skipped-1")));
4161 assert_eq!(de.next().unwrap(), End(BytesEnd::new("skipped-1")));
4162 assert_eq!(de.next().unwrap(), Start(BytesStart::new("skipped-2")));
4163 assert_eq!(de.next().unwrap(), End(BytesEnd::new("skipped-2")));
4164
4165 assert_eq!(de.read, vec![]);
4166 assert_eq!(de.write, vec![]);
4167
4168 // New events
4169 assert_eq!(de.next().unwrap(), End(BytesEnd::new("root")));
4170 assert_eq!(de.next().unwrap(), Eof);
4171 }
4172
4173 /// Checks that limiting buffer size works correctly
4174 #[test]
4175 fn limit() {
4176 use serde::Deserialize;
4177
4178 #[derive(Debug, Deserialize)]
4179 #[allow(unused)]
4180 struct List {
4181 item: Vec<()>,
4182 }
4183
4184 let mut de = make_de(
4185 "\
4186 <any-name>\
4187 <item/>\
4188 <another-item>\
4189 <some-element>with text</some-element>\
4190 <yet-another-element/>\
4191 </another-item>\
4192 <item/>\
4193 <item/>\
4194 </any-name>\
4195 ",
4196 );
4197 de.event_buffer_size(NonZeroUsize::new(3));
4198
4199 match List::deserialize(&mut de) {
4200 Err(DeError::TooManyEvents(count)) => assert_eq!(count.get(), 3),
4201 e => panic!("Expected `Err(TooManyEvents(3))`, but got `{:?}`", e),
4202 }
4203 }
4204
4205 /// Without handling Eof in `skip` this test failed with memory allocation
4206 #[test]
4207 fn invalid_xml() {
4208 use crate::de::DeEvent::*;
4209
4210 let mut de = make_de("<root>");
4211
4212 // Cache all events
4213 let checkpoint = de.skip_checkpoint();
4214 de.skip().unwrap();
4215 de.start_replay(checkpoint);
4216 assert_eq!(de.read, vec![Start(BytesStart::new("root")), Eof]);
4217 }
4218 }
4219
4220 mod read_to_end {
4221 use super::*;
4222 use crate::de::DeEvent::*;
4223 use pretty_assertions::assert_eq;
4224
4225 #[test]
4226 fn complex() {
4227 let mut de = make_de(
4228 r#"
4229 <root>
4230 <tag a="1"><tag>text</tag>content</tag>
4231 <tag a="2"><![CDATA[cdata content]]></tag>
4232 <self-closed/>
4233 </root>
4234 "#,
4235 );
4236
4237 assert_eq!(de.next().unwrap(), Text("\n ".into()));
4238 assert_eq!(de.next().unwrap(), Start(BytesStart::new("root")));
4239
4240 assert_eq!(de.next().unwrap(), Text("\n ".into()));
4241 assert_eq!(
4242 de.next().unwrap(),
4243 Start(BytesStart::from_content(r#"tag a="1""#, 3))
4244 );
4245 assert_eq!(de.read_to_end(QName("tag")).unwrap(), ());
4246
4247 assert_eq!(de.next().unwrap(), Text("\n ".into()));
4248 assert_eq!(
4249 de.next().unwrap(),
4250 Start(BytesStart::from_content(r#"tag a="2""#, 3))
4251 );
4252 assert_eq!(de.next().unwrap(), Text("cdata content".into()));
4253 assert_eq!(de.next().unwrap(), End(BytesEnd::new("tag")));
4254
4255 assert_eq!(de.next().unwrap(), Text("\n ".into()));
4256 assert_eq!(de.next().unwrap(), Start(BytesStart::new("self-closed")));
4257 assert_eq!(de.read_to_end(QName("self-closed")).unwrap(), ());
4258
4259 assert_eq!(de.next().unwrap(), Text("\n ".into()));
4260 assert_eq!(de.next().unwrap(), End(BytesEnd::new("root")));
4261 assert_eq!(de.next().unwrap(), Text("\n ".into()));
4262 assert_eq!(de.next().unwrap(), Eof);
4263 }
4264
4265 #[test]
4266 fn invalid_xml1() {
4267 let mut de = make_de("<tag><tag></tag>");
4268
4269 assert_eq!(de.next().unwrap(), Start(BytesStart::new("tag")));
4270 assert_eq!(de.peek().unwrap(), &Start(BytesStart::new("tag")));
4271
4272 match de.read_to_end(QName("tag")) {
4273 Err(DeError::InvalidXml(Error::IllFormed(cause))) => {
4274 assert_eq!(cause, IllFormedError::MissingEndTag("tag".into()))
4275 }
4276 x => panic!(
4277 "Expected `Err(InvalidXml(IllFormed(_)))`, but got `{:?}`",
4278 x
4279 ),
4280 }
4281 assert_eq!(de.next().unwrap(), Eof);
4282 }
4283
4284 #[test]
4285 fn invalid_xml2() {
4286 let mut de = make_de("<tag><![CDATA[]]><tag></tag>");
4287
4288 assert_eq!(de.next().unwrap(), Start(BytesStart::new("tag")));
4289 assert_eq!(de.peek().unwrap(), &Text("".into()));
4290
4291 match de.read_to_end(QName("tag")) {
4292 Err(DeError::InvalidXml(Error::IllFormed(cause))) => {
4293 assert_eq!(cause, IllFormedError::MissingEndTag("tag".into()))
4294 }
4295 x => panic!(
4296 "Expected `Err(InvalidXml(IllFormed(_)))`, but got `{:?}`",
4297 x
4298 ),
4299 }
4300 assert_eq!(de.next().unwrap(), Eof);
4301 }
4302 }
4303
4304 #[test]
4305 fn borrowing_reader_parity() {
4306 let s = r#"
4307 <item name="hello" source="world.rs">Some text</item>
4308 <item2/>
4309 <item3 value="world" />
4310 "#;
4311
4312 let mut reader1 = IoReader {
4313 reader: Reader::from_reader(s.as_bytes()),
4314 buf: Vec::new(),
4315 version: XmlVersion::Implicit1_0,
4316 };
4317 let mut reader2 = SliceReader {
4318 reader: Reader::from_str(s),
4319 version: XmlVersion::Implicit1_0,
4320 };
4321
4322 loop {
4323 let event1 = reader1.next().unwrap();
4324 let event2 = reader2.next().unwrap();
4325
4326 if let (PayloadEvent::Eof, PayloadEvent::Eof) = (&event1, &event2) {
4327 break;
4328 }
4329
4330 assert_eq!(event1, event2);
4331 }
4332 }
4333
4334 #[test]
4335 fn borrowing_reader_events() {
4336 let s = r#"
4337 <item name="hello" source="world.rs">Some text</item>
4338 <item2></item2>
4339 <item3/>
4340 <item4 value="world" />
4341 "#;
4342
4343 let mut reader = SliceReader {
4344 reader: Reader::from_str(s),
4345 version: XmlVersion::Implicit1_0,
4346 };
4347
4348 let config = reader.reader.config_mut();
4349 config.expand_empty_elements = true;
4350
4351 let mut events = Vec::new();
4352
4353 loop {
4354 let event = reader.next().unwrap();
4355 if let PayloadEvent::Eof = event {
4356 break;
4357 }
4358 events.push(event);
4359 }
4360
4361 use crate::de::PayloadEvent::*;
4362
4363 assert_eq!(
4364 events,
4365 vec![
4366 Text(BytesText::from_escaped("\n ")),
4367 Start(BytesStart::from_content(
4368 r#"item name="hello" source="world.rs""#,
4369 4
4370 )),
4371 Text(BytesText::from_escaped("Some text")),
4372 End(BytesEnd::new("item")),
4373 Text(BytesText::from_escaped("\n ")),
4374 Start(BytesStart::from_content("item2", 5)),
4375 End(BytesEnd::new("item2")),
4376 Text(BytesText::from_escaped("\n ")),
4377 Start(BytesStart::from_content("item3", 5)),
4378 End(BytesEnd::new("item3")),
4379 Text(BytesText::from_escaped("\n ")),
4380 Start(BytesStart::from_content(r#"item4 value="world" "#, 5)),
4381 End(BytesEnd::new("item4")),
4382 Text(BytesText::from_escaped("\n ")),
4383 ]
4384 )
4385 }
4386
4387 /// Ensures, that [`Deserializer::read_string()`] never can get an `End` event,
4388 /// because parser reports error early
4389 #[test]
4390 fn read_string() {
4391 match from_str::<String>(r#"</root>"#) {
4392 Err(DeError::InvalidXml(Error::IllFormed(cause))) => {
4393 assert_eq!(cause, IllFormedError::UnmatchedEndTag("root".into()));
4394 }
4395 x => panic!(
4396 "Expected `Err(InvalidXml(IllFormed(_)))`, but got `{:?}`",
4397 x
4398 ),
4399 }
4400
4401 let s: String = from_str(r#"<root></root>"#).unwrap();
4402 assert_eq!(s, "");
4403
4404 match from_str::<String>(r#"<root></other>"#) {
4405 Err(DeError::InvalidXml(Error::IllFormed(cause))) => assert_eq!(
4406 cause,
4407 IllFormedError::MismatchedEndTag {
4408 expected: "root".into(),
4409 found: "other".into(),
4410 }
4411 ),
4412 x => panic!("Expected `Err(InvalidXml(IllFormed(_))`, but got `{:?}`", x),
4413 }
4414 }
4415
4416 /// Tests for https://github.com/tafia/quick-xml/issues/474.
4417 ///
4418 /// That tests ensures that comments and processed instructions is ignored
4419 /// and can split one logical string in pieces.
4420 mod merge_text {
4421 use super::*;
4422 use pretty_assertions::assert_eq;
4423
4424 #[test]
4425 fn text() {
4426 let mut de = make_de("text");
4427 assert_eq!(de.next().unwrap(), DeEvent::Text("text".into()));
4428 }
4429
4430 #[test]
4431 fn cdata() {
4432 let mut de = make_de("<![CDATA[cdata]]>");
4433 assert_eq!(de.next().unwrap(), DeEvent::Text("cdata".into()));
4434 }
4435
4436 #[test]
4437 fn text_and_cdata() {
4438 let mut de = make_de("text and <![CDATA[cdata]]>");
4439 assert_eq!(de.next().unwrap(), DeEvent::Text("text and cdata".into()));
4440 }
4441
4442 #[test]
4443 fn text_and_empty_cdata() {
4444 let mut de = make_de("text and <![CDATA[]]>");
4445 assert_eq!(de.next().unwrap(), DeEvent::Text("text and ".into()));
4446 }
4447
4448 #[test]
4449 fn cdata_and_text() {
4450 let mut de = make_de("<![CDATA[cdata]]> and text");
4451 assert_eq!(de.next().unwrap(), DeEvent::Text("cdata and text".into()));
4452 }
4453
4454 #[test]
4455 fn empty_cdata_and_text() {
4456 let mut de = make_de("<![CDATA[]]> and text");
4457 assert_eq!(de.next().unwrap(), DeEvent::Text(" and text".into()));
4458 }
4459
4460 #[test]
4461 fn cdata_and_cdata() {
4462 let mut de = make_de(
4463 "\
4464 <![CDATA[cdata]]]]>\
4465 <![CDATA[>cdata]]>\
4466 ",
4467 );
4468 assert_eq!(de.next().unwrap(), DeEvent::Text("cdata]]>cdata".into()));
4469 }
4470
4471 mod comment_between {
4472 use super::*;
4473 use pretty_assertions::assert_eq;
4474
4475 #[test]
4476 fn text() {
4477 let mut de = make_de(
4478 "\
4479 text \
4480 <!--comment 1--><!--comment 2--> \
4481 text\
4482 ",
4483 );
4484 assert_eq!(de.next().unwrap(), DeEvent::Text("text text".into()));
4485 }
4486
4487 #[test]
4488 fn cdata() {
4489 let mut de = make_de(
4490 "\
4491 <![CDATA[cdata]]]]>\
4492 <!--comment 1--><!--comment 2-->\
4493 <![CDATA[>cdata]]>\
4494 ",
4495 );
4496 assert_eq!(de.next().unwrap(), DeEvent::Text("cdata]]>cdata".into()));
4497 }
4498
4499 #[test]
4500 fn text_and_cdata() {
4501 let mut de = make_de(
4502 "\
4503 text \
4504 <!--comment 1--><!--comment 2-->\
4505 <![CDATA[ cdata]]>\
4506 ",
4507 );
4508 assert_eq!(de.next().unwrap(), DeEvent::Text("text cdata".into()));
4509 }
4510
4511 #[test]
4512 fn text_and_empty_cdata() {
4513 let mut de = make_de(
4514 "\
4515 text \
4516 <!--comment 1--><!--comment 2-->\
4517 <![CDATA[]]>\
4518 ",
4519 );
4520 assert_eq!(de.next().unwrap(), DeEvent::Text("text ".into()));
4521 }
4522
4523 #[test]
4524 fn cdata_and_text() {
4525 let mut de = make_de(
4526 "\
4527 <![CDATA[cdata ]]>\
4528 <!--comment 1--><!--comment 2--> \
4529 text \
4530 ",
4531 );
4532 assert_eq!(de.next().unwrap(), DeEvent::Text("cdata text ".into()));
4533 }
4534
4535 #[test]
4536 fn empty_cdata_and_text() {
4537 let mut de = make_de(
4538 "\
4539 <![CDATA[]]>\
4540 <!--comment 1--><!--comment 2--> \
4541 text \
4542 ",
4543 );
4544 assert_eq!(de.next().unwrap(), DeEvent::Text(" text ".into()));
4545 }
4546
4547 #[test]
4548 fn cdata_and_cdata() {
4549 let mut de = make_de(
4550 "\
4551 <![CDATA[cdata]]]>\
4552 <!--comment 1--><!--comment 2-->\
4553 <![CDATA[]>cdata]]>\
4554 ",
4555 );
4556 assert_eq!(de.next().unwrap(), DeEvent::Text("cdata]]>cdata".into()));
4557 }
4558 }
4559
4560 mod pi_between {
4561 use super::*;
4562 use pretty_assertions::assert_eq;
4563
4564 #[test]
4565 fn text() {
4566 let mut de = make_de(
4567 "\
4568 text \
4569 <?pi 1?><?pi 2?> \
4570 text\
4571 ",
4572 );
4573 assert_eq!(de.next().unwrap(), DeEvent::Text("text text".into()));
4574 }
4575
4576 #[test]
4577 fn cdata() {
4578 let mut de = make_de(
4579 "\
4580 <![CDATA[cdata]]]]>\
4581 <?pi 1?><?pi 2?>\
4582 <![CDATA[>cdata]]>\
4583 ",
4584 );
4585 assert_eq!(de.next().unwrap(), DeEvent::Text("cdata]]>cdata".into()));
4586 }
4587
4588 #[test]
4589 fn text_and_cdata() {
4590 let mut de = make_de(
4591 "\
4592 text \
4593 <?pi 1?><?pi 2?>\
4594 <![CDATA[ cdata]]>\
4595 ",
4596 );
4597 assert_eq!(de.next().unwrap(), DeEvent::Text("text cdata".into()));
4598 }
4599
4600 #[test]
4601 fn text_and_empty_cdata() {
4602 let mut de = make_de(
4603 "\
4604 text \
4605 <?pi 1?><?pi 2?>\
4606 <![CDATA[]]>\
4607 ",
4608 );
4609 assert_eq!(de.next().unwrap(), DeEvent::Text("text ".into()));
4610 }
4611
4612 #[test]
4613 fn cdata_and_text() {
4614 let mut de = make_de(
4615 "\
4616 <![CDATA[cdata ]]>\
4617 <?pi 1?><?pi 2?> \
4618 text \
4619 ",
4620 );
4621 assert_eq!(de.next().unwrap(), DeEvent::Text("cdata text ".into()));
4622 }
4623
4624 #[test]
4625 fn empty_cdata_and_text() {
4626 let mut de = make_de(
4627 "\
4628 <![CDATA[]]>\
4629 <?pi 1?><?pi 2?> \
4630 text \
4631 ",
4632 );
4633 assert_eq!(de.next().unwrap(), DeEvent::Text(" text ".into()));
4634 }
4635
4636 #[test]
4637 fn cdata_and_cdata() {
4638 let mut de = make_de(
4639 "\
4640 <![CDATA[cdata]]]>\
4641 <?pi 1?><?pi 2?>\
4642 <![CDATA[]>cdata]]>\
4643 ",
4644 );
4645 assert_eq!(de.next().unwrap(), DeEvent::Text("cdata]]>cdata".into()));
4646 }
4647 }
4648 }
4649
4650 /// Tests for https://github.com/tafia/quick-xml/issues/474.
4651 ///
4652 /// This tests ensures that any combination of payload data is processed
4653 /// as expected.
4654 mod triples {
4655 use super::*;
4656 use pretty_assertions::assert_eq;
4657
4658 mod start {
4659 use super::*;
4660
4661 /// <tag1><tag2>...
4662 // The same name is intentional
4663 #[allow(clippy::module_inception)]
4664 mod start {
4665 use super::*;
4666 use pretty_assertions::assert_eq;
4667
4668 #[test]
4669 fn start() {
4670 let mut de = make_de("<tag1><tag2><tag3>");
4671 assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag1")));
4672 assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag2")));
4673 assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag3")));
4674 assert_eq!(de.next().unwrap(), DeEvent::Eof);
4675 }
4676
4677 /// Not matching end tag will result to error
4678 #[test]
4679 fn end() {
4680 let mut de = make_de("<tag1><tag2></tag2>");
4681 assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag1")));
4682 assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag2")));
4683 assert_eq!(de.next().unwrap(), DeEvent::End(BytesEnd::new("tag2")));
4684 assert_eq!(de.next().unwrap(), DeEvent::Eof);
4685 }
4686
4687 #[test]
4688 fn text() {
4689 let mut de = make_de("<tag1><tag2> text ");
4690 assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag1")));
4691 assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag2")));
4692 assert_eq!(de.next().unwrap(), DeEvent::Text(" text ".into()));
4693 assert_eq!(de.next().unwrap(), DeEvent::Eof);
4694 }
4695
4696 #[test]
4697 fn cdata() {
4698 let mut de = make_de("<tag1><tag2><![CDATA[ cdata ]]>");
4699 assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag1")));
4700 assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag2")));
4701 assert_eq!(de.next().unwrap(), DeEvent::Text(" cdata ".into()));
4702 assert_eq!(de.next().unwrap(), DeEvent::Eof);
4703 }
4704
4705 #[test]
4706 fn eof() {
4707 let mut de = make_de("<tag1><tag2>");
4708 assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag1")));
4709 assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag2")));
4710 assert_eq!(de.next().unwrap(), DeEvent::Eof);
4711 assert_eq!(de.next().unwrap(), DeEvent::Eof);
4712 }
4713 }
4714
4715 /// <tag></tag>...
4716 mod end {
4717 use super::*;
4718 use pretty_assertions::assert_eq;
4719
4720 #[test]
4721 fn start() {
4722 let mut de = make_de("<tag></tag><tag2>");
4723 assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag")));
4724 assert_eq!(de.next().unwrap(), DeEvent::End(BytesEnd::new("tag")));
4725 assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag2")));
4726 assert_eq!(de.next().unwrap(), DeEvent::Eof);
4727 }
4728
4729 #[test]
4730 fn end() {
4731 let mut de = make_de("<tag></tag></tag2>");
4732 assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag")));
4733 assert_eq!(de.next().unwrap(), DeEvent::End(BytesEnd::new("tag")));
4734 match de.next() {
4735 Err(DeError::InvalidXml(Error::IllFormed(cause))) => {
4736 assert_eq!(cause, IllFormedError::UnmatchedEndTag("tag2".into()));
4737 }
4738 x => panic!(
4739 "Expected `Err(InvalidXml(IllFormed(_)))`, but got `{:?}`",
4740 x
4741 ),
4742 }
4743 assert_eq!(de.next().unwrap(), DeEvent::Eof);
4744 }
4745
4746 #[test]
4747 fn text() {
4748 let mut de = make_de("<tag></tag> text ");
4749 assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag")));
4750 assert_eq!(de.next().unwrap(), DeEvent::End(BytesEnd::new("tag")));
4751 assert_eq!(de.next().unwrap(), DeEvent::Text(" text ".into()));
4752 assert_eq!(de.next().unwrap(), DeEvent::Eof);
4753 }
4754
4755 #[test]
4756 fn cdata() {
4757 let mut de = make_de("<tag></tag><![CDATA[ cdata ]]>");
4758 assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag")));
4759 assert_eq!(de.next().unwrap(), DeEvent::End(BytesEnd::new("tag")));
4760 assert_eq!(de.next().unwrap(), DeEvent::Text(" cdata ".into()));
4761 assert_eq!(de.next().unwrap(), DeEvent::Eof);
4762 }
4763
4764 #[test]
4765 fn eof() {
4766 let mut de = make_de("<tag></tag>");
4767 assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag")));
4768 assert_eq!(de.next().unwrap(), DeEvent::End(BytesEnd::new("tag")));
4769 assert_eq!(de.next().unwrap(), DeEvent::Eof);
4770 assert_eq!(de.next().unwrap(), DeEvent::Eof);
4771 }
4772 }
4773
4774 /// <tag> text ...
4775 mod text {
4776 use super::*;
4777 use pretty_assertions::assert_eq;
4778
4779 #[test]
4780 fn start() {
4781 let mut de = make_de("<tag> text <tag2>");
4782 assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag")));
4783 assert_eq!(de.next().unwrap(), DeEvent::Text(" text ".into()));
4784 assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag2")));
4785 assert_eq!(de.next().unwrap(), DeEvent::Eof);
4786 }
4787
4788 #[test]
4789 fn end() {
4790 let mut de = make_de("<tag> text </tag>");
4791 assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag")));
4792 assert_eq!(de.next().unwrap(), DeEvent::Text(" text ".into()));
4793 assert_eq!(de.next().unwrap(), DeEvent::End(BytesEnd::new("tag")));
4794 assert_eq!(de.next().unwrap(), DeEvent::Eof);
4795 }
4796
4797 // start::text::text has no difference from start::text
4798
4799 #[test]
4800 fn cdata() {
4801 let mut de = make_de("<tag> text <![CDATA[ cdata ]]>");
4802 assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag")));
4803 assert_eq!(de.next().unwrap(), DeEvent::Text(" text cdata ".into()));
4804 assert_eq!(de.next().unwrap(), DeEvent::Eof);
4805 }
4806
4807 #[test]
4808 fn eof() {
4809 let mut de = make_de("<tag> text ");
4810 assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag")));
4811 assert_eq!(de.next().unwrap(), DeEvent::Text(" text ".into()));
4812 assert_eq!(de.next().unwrap(), DeEvent::Eof);
4813 assert_eq!(de.next().unwrap(), DeEvent::Eof);
4814 }
4815 }
4816
4817 /// <tag><![CDATA[ cdata ]]>...
4818 mod cdata {
4819 use super::*;
4820 use pretty_assertions::assert_eq;
4821
4822 #[test]
4823 fn start() {
4824 let mut de = make_de("<tag><![CDATA[ cdata ]]><tag2>");
4825 assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag")));
4826 assert_eq!(de.next().unwrap(), DeEvent::Text(" cdata ".into()));
4827 assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag2")));
4828 assert_eq!(de.next().unwrap(), DeEvent::Eof);
4829 }
4830
4831 #[test]
4832 fn end() {
4833 let mut de = make_de("<tag><![CDATA[ cdata ]]></tag>");
4834 assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag")));
4835 assert_eq!(de.next().unwrap(), DeEvent::Text(" cdata ".into()));
4836 assert_eq!(de.next().unwrap(), DeEvent::End(BytesEnd::new("tag")));
4837 assert_eq!(de.next().unwrap(), DeEvent::Eof);
4838 }
4839
4840 #[test]
4841 fn text() {
4842 let mut de = make_de("<tag><![CDATA[ cdata ]]> text ");
4843 assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag")));
4844 assert_eq!(de.next().unwrap(), DeEvent::Text(" cdata text ".into()));
4845 assert_eq!(de.next().unwrap(), DeEvent::Eof);
4846 }
4847
4848 #[test]
4849 fn cdata() {
4850 let mut de = make_de("<tag><![CDATA[ cdata ]]><![CDATA[ cdata2 ]]>");
4851 assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag")));
4852 assert_eq!(de.next().unwrap(), DeEvent::Text(" cdata cdata2 ".into()));
4853 assert_eq!(de.next().unwrap(), DeEvent::Eof);
4854 }
4855
4856 #[test]
4857 fn eof() {
4858 let mut de = make_de("<tag><![CDATA[ cdata ]]>");
4859 assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag")));
4860 assert_eq!(de.next().unwrap(), DeEvent::Text(" cdata ".into()));
4861 assert_eq!(de.next().unwrap(), DeEvent::Eof);
4862 assert_eq!(de.next().unwrap(), DeEvent::Eof);
4863 }
4864 }
4865 }
4866
4867 /// Start from End event will always generate an error
4868 #[test]
4869 fn end() {
4870 let mut de = make_de("</tag>");
4871 match de.next() {
4872 Err(DeError::InvalidXml(Error::IllFormed(cause))) => {
4873 assert_eq!(cause, IllFormedError::UnmatchedEndTag("tag".into()));
4874 }
4875 x => panic!(
4876 "Expected `Err(InvalidXml(IllFormed(_)))`, but got `{:?}`",
4877 x
4878 ),
4879 }
4880 assert_eq!(de.next().unwrap(), DeEvent::Eof);
4881 }
4882
4883 mod text {
4884 use super::*;
4885 use pretty_assertions::assert_eq;
4886
4887 mod start {
4888 use super::*;
4889 use pretty_assertions::assert_eq;
4890
4891 #[test]
4892 fn start() {
4893 let mut de = make_de(" text <tag1><tag2>");
4894 assert_eq!(de.next().unwrap(), DeEvent::Text(" text ".into()));
4895 assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag1")));
4896 assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag2")));
4897 assert_eq!(de.next().unwrap(), DeEvent::Eof);
4898 }
4899
4900 /// Not matching end tag will result in error
4901 #[test]
4902 fn end() {
4903 let mut de = make_de(" text <tag></tag>");
4904 assert_eq!(de.next().unwrap(), DeEvent::Text(" text ".into()));
4905 assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag")));
4906 assert_eq!(de.next().unwrap(), DeEvent::End(BytesEnd::new("tag")));
4907 assert_eq!(de.next().unwrap(), DeEvent::Eof);
4908 }
4909
4910 #[test]
4911 fn text() {
4912 let mut de = make_de(" text <tag> text2 ");
4913 assert_eq!(de.next().unwrap(), DeEvent::Text(" text ".into()));
4914 assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag")));
4915 assert_eq!(de.next().unwrap(), DeEvent::Text(" text2 ".into()));
4916 assert_eq!(de.next().unwrap(), DeEvent::Eof);
4917 }
4918
4919 #[test]
4920 fn cdata() {
4921 let mut de = make_de(" text <tag><![CDATA[ cdata ]]>");
4922 assert_eq!(de.next().unwrap(), DeEvent::Text(" text ".into()));
4923 assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag")));
4924 assert_eq!(de.next().unwrap(), DeEvent::Text(" cdata ".into()));
4925 assert_eq!(de.next().unwrap(), DeEvent::Eof);
4926 }
4927
4928 #[test]
4929 fn eof() {
4930 let mut de = make_de(" text <tag>");
4931 assert_eq!(de.next().unwrap(), DeEvent::Text(" text ".into()));
4932 assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag")));
4933 assert_eq!(de.next().unwrap(), DeEvent::Eof);
4934 assert_eq!(de.next().unwrap(), DeEvent::Eof);
4935 }
4936 }
4937
4938 /// End event without corresponding start event will always generate an error
4939 #[test]
4940 fn end() {
4941 let mut de = make_de(" text </tag>");
4942 assert_eq!(de.next().unwrap(), DeEvent::Text(" text ".into()));
4943 match de.next() {
4944 Err(DeError::InvalidXml(Error::IllFormed(cause))) => {
4945 assert_eq!(cause, IllFormedError::UnmatchedEndTag("tag".into()));
4946 }
4947 x => panic!(
4948 "Expected `Err(InvalidXml(IllFormed(_)))`, but got `{:?}`",
4949 x
4950 ),
4951 }
4952 assert_eq!(de.next().unwrap(), DeEvent::Eof);
4953 }
4954
4955 // text::text::something is equivalent to text::something
4956
4957 mod cdata {
4958 use super::*;
4959 use pretty_assertions::assert_eq;
4960
4961 #[test]
4962 fn start() {
4963 let mut de = make_de(" text <![CDATA[ cdata ]]><tag>");
4964 assert_eq!(de.next().unwrap(), DeEvent::Text(" text cdata ".into()));
4965 assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag")));
4966 assert_eq!(de.next().unwrap(), DeEvent::Eof);
4967 }
4968
4969 #[test]
4970 fn end() {
4971 let mut de = make_de(" text <![CDATA[ cdata ]]></tag>");
4972 assert_eq!(de.next().unwrap(), DeEvent::Text(" text cdata ".into()));
4973 match de.next() {
4974 Err(DeError::InvalidXml(Error::IllFormed(cause))) => {
4975 assert_eq!(cause, IllFormedError::UnmatchedEndTag("tag".into()));
4976 }
4977 x => panic!(
4978 "Expected `Err(InvalidXml(IllFormed(_)))`, but got `{:?}`",
4979 x
4980 ),
4981 }
4982 assert_eq!(de.next().unwrap(), DeEvent::Eof);
4983 }
4984
4985 #[test]
4986 fn text() {
4987 let mut de = make_de(" text <![CDATA[ cdata ]]> text2 ");
4988 assert_eq!(
4989 de.next().unwrap(),
4990 DeEvent::Text(" text cdata text2 ".into())
4991 );
4992 assert_eq!(de.next().unwrap(), DeEvent::Eof);
4993 }
4994
4995 #[test]
4996 fn cdata() {
4997 let mut de = make_de(" text <![CDATA[ cdata ]]><![CDATA[ cdata2 ]]>");
4998 assert_eq!(
4999 de.next().unwrap(),
5000 DeEvent::Text(" text cdata cdata2 ".into())
5001 );
5002 assert_eq!(de.next().unwrap(), DeEvent::Eof);
5003 }
5004
5005 #[test]
5006 fn eof() {
5007 let mut de = make_de(" text <![CDATA[ cdata ]]>");
5008 assert_eq!(de.next().unwrap(), DeEvent::Text(" text cdata ".into()));
5009 assert_eq!(de.next().unwrap(), DeEvent::Eof);
5010 assert_eq!(de.next().unwrap(), DeEvent::Eof);
5011 }
5012 }
5013 }
5014
5015 mod cdata {
5016 use super::*;
5017 use pretty_assertions::assert_eq;
5018
5019 mod start {
5020 use super::*;
5021 use pretty_assertions::assert_eq;
5022
5023 #[test]
5024 fn start() {
5025 let mut de = make_de("<![CDATA[ cdata ]]><tag1><tag2>");
5026 assert_eq!(de.next().unwrap(), DeEvent::Text(" cdata ".into()));
5027 assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag1")));
5028 assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag2")));
5029 assert_eq!(de.next().unwrap(), DeEvent::Eof);
5030 }
5031
5032 /// Not matching end tag will result in error
5033 #[test]
5034 fn end() {
5035 let mut de = make_de("<![CDATA[ cdata ]]><tag></tag>");
5036 assert_eq!(de.next().unwrap(), DeEvent::Text(" cdata ".into()));
5037 assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag")));
5038 assert_eq!(de.next().unwrap(), DeEvent::End(BytesEnd::new("tag")));
5039 assert_eq!(de.next().unwrap(), DeEvent::Eof);
5040 }
5041
5042 #[test]
5043 fn text() {
5044 let mut de = make_de("<![CDATA[ cdata ]]><tag> text ");
5045 assert_eq!(de.next().unwrap(), DeEvent::Text(" cdata ".into()));
5046 assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag")));
5047 assert_eq!(de.next().unwrap(), DeEvent::Text(" text ".into()));
5048 assert_eq!(de.next().unwrap(), DeEvent::Eof);
5049 }
5050
5051 #[test]
5052 fn cdata() {
5053 let mut de = make_de("<![CDATA[ cdata ]]><tag><![CDATA[ cdata2 ]]>");
5054 assert_eq!(de.next().unwrap(), DeEvent::Text(" cdata ".into()));
5055 assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag")));
5056 assert_eq!(de.next().unwrap(), DeEvent::Text(" cdata2 ".into()));
5057 assert_eq!(de.next().unwrap(), DeEvent::Eof);
5058 }
5059
5060 #[test]
5061 fn eof() {
5062 let mut de = make_de("<![CDATA[ cdata ]]><tag>");
5063 assert_eq!(de.next().unwrap(), DeEvent::Text(" cdata ".into()));
5064 assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag")));
5065 assert_eq!(de.next().unwrap(), DeEvent::Eof);
5066 assert_eq!(de.next().unwrap(), DeEvent::Eof);
5067 }
5068 }
5069
5070 /// End event without corresponding start event will always generate an error
5071 #[test]
5072 fn end() {
5073 let mut de = make_de("<![CDATA[ cdata ]]></tag>");
5074 assert_eq!(de.next().unwrap(), DeEvent::Text(" cdata ".into()));
5075 match de.next() {
5076 Err(DeError::InvalidXml(Error::IllFormed(cause))) => {
5077 assert_eq!(cause, IllFormedError::UnmatchedEndTag("tag".into()));
5078 }
5079 x => panic!(
5080 "Expected `Err(InvalidXml(IllFormed(_)))`, but got `{:?}`",
5081 x
5082 ),
5083 }
5084 assert_eq!(de.next().unwrap(), DeEvent::Eof);
5085 }
5086
5087 mod text {
5088 use super::*;
5089 use pretty_assertions::assert_eq;
5090
5091 #[test]
5092 fn start() {
5093 let mut de = make_de("<![CDATA[ cdata ]]> text <tag>");
5094 assert_eq!(de.next().unwrap(), DeEvent::Text(" cdata text ".into()));
5095 assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag")));
5096 assert_eq!(de.next().unwrap(), DeEvent::Eof);
5097 }
5098
5099 #[test]
5100 fn end() {
5101 let mut de = make_de("<![CDATA[ cdata ]]> text </tag>");
5102 assert_eq!(de.next().unwrap(), DeEvent::Text(" cdata text ".into()));
5103 match de.next() {
5104 Err(DeError::InvalidXml(Error::IllFormed(cause))) => {
5105 assert_eq!(cause, IllFormedError::UnmatchedEndTag("tag".into()));
5106 }
5107 x => panic!(
5108 "Expected `Err(InvalidXml(IllFormed(_)))`, but got `{:?}`",
5109 x
5110 ),
5111 }
5112 assert_eq!(de.next().unwrap(), DeEvent::Eof);
5113 }
5114
5115 // cdata::text::text is equivalent to cdata::text
5116
5117 #[test]
5118 fn cdata() {
5119 let mut de = make_de("<![CDATA[ cdata ]]> text <![CDATA[ cdata2 ]]>");
5120 assert_eq!(
5121 de.next().unwrap(),
5122 DeEvent::Text(" cdata text cdata2 ".into())
5123 );
5124 assert_eq!(de.next().unwrap(), DeEvent::Eof);
5125 }
5126
5127 #[test]
5128 fn eof() {
5129 let mut de = make_de("<![CDATA[ cdata ]]> text ");
5130 assert_eq!(de.next().unwrap(), DeEvent::Text(" cdata text ".into()));
5131 assert_eq!(de.next().unwrap(), DeEvent::Eof);
5132 assert_eq!(de.next().unwrap(), DeEvent::Eof);
5133 }
5134 }
5135
5136 // The same name is intentional
5137 #[allow(clippy::module_inception)]
5138 mod cdata {
5139 use super::*;
5140 use pretty_assertions::assert_eq;
5141
5142 #[test]
5143 fn start() {
5144 let mut de = make_de("<![CDATA[ cdata ]]><![CDATA[ cdata2 ]]><tag>");
5145 assert_eq!(de.next().unwrap(), DeEvent::Text(" cdata cdata2 ".into()));
5146 assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag")));
5147 assert_eq!(de.next().unwrap(), DeEvent::Eof);
5148 }
5149
5150 #[test]
5151 fn end() {
5152 let mut de = make_de("<![CDATA[ cdata ]]><![CDATA[ cdata2 ]]></tag>");
5153 assert_eq!(de.next().unwrap(), DeEvent::Text(" cdata cdata2 ".into()));
5154 match de.next() {
5155 Err(DeError::InvalidXml(Error::IllFormed(cause))) => {
5156 assert_eq!(cause, IllFormedError::UnmatchedEndTag("tag".into()));
5157 }
5158 x => panic!(
5159 "Expected `Err(InvalidXml(IllFormed(_)))`, but got `{:?}`",
5160 x
5161 ),
5162 }
5163 assert_eq!(de.next().unwrap(), DeEvent::Eof);
5164 }
5165
5166 #[test]
5167 fn text() {
5168 let mut de = make_de("<![CDATA[ cdata ]]><![CDATA[ cdata2 ]]> text ");
5169 assert_eq!(
5170 de.next().unwrap(),
5171 DeEvent::Text(" cdata cdata2 text ".into())
5172 );
5173 assert_eq!(de.next().unwrap(), DeEvent::Eof);
5174 }
5175
5176 #[test]
5177 fn cdata() {
5178 let mut de =
5179 make_de("<![CDATA[ cdata ]]><![CDATA[ cdata2 ]]><![CDATA[ cdata3 ]]>");
5180 assert_eq!(
5181 de.next().unwrap(),
5182 DeEvent::Text(" cdata cdata2 cdata3 ".into())
5183 );
5184 assert_eq!(de.next().unwrap(), DeEvent::Eof);
5185 }
5186
5187 #[test]
5188 fn eof() {
5189 let mut de = make_de("<![CDATA[ cdata ]]><![CDATA[ cdata2 ]]>");
5190 assert_eq!(de.next().unwrap(), DeEvent::Text(" cdata cdata2 ".into()));
5191 assert_eq!(de.next().unwrap(), DeEvent::Eof);
5192 assert_eq!(de.next().unwrap(), DeEvent::Eof);
5193 }
5194 }
5195 }
5196 }
5197}