1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
//! Serde-driven XML deserialization.
//!
//! Map XML directly into typed Rust values:
//!
//! ```
//! use serde::Deserialize;
//!
//! #[derive(Deserialize, Debug, PartialEq)]
//! struct Page {
//! #[serde(rename = "@id")]
//! id: u32,
//! title: String,
//! }
//!
//! let xml = r#"<page id="7"><title>hello</title></page>"#;
//! let page: Page = sup_xml::de::from_str(xml).unwrap();
//! assert_eq!(page, Page { id: 7, title: "hello".into() });
//! ```
//!
//! # XML → serde conventions
//!
//! | XML construct | Serde concept | Field name |
//! |------------------------------|---------------------------|--------------------|
//! | Element attribute | struct field | `@name` |
//! | Element text-only content | scalar / string field | (the field itself) |
//! | Element with children | struct | element name |
//! | Repeated same-name children | `Vec<T>` | element name |
//! | Optional element | `Option<T>` | element name |
//! | Mixed text + child elements | struct field | `$text` |
//! | Heterogeneous element body | enum sequence | `$value` |
//!
//! `$text` collects all text/CDATA between the start and end tag — atomic
//! content only (primitives, strings, unit enums, space-delimited lists).
//! `$value` collects child *elements* — each one becomes a sequence item,
//! and for enum types the element tag picks the variant. If both are
//! declared on the same struct, text routes to `$text` and remaining child
//! elements route to `$value`.
//!
//! # Borrowed deserialization
//!
//! Deserializing into `&'de str` borrows directly from the source. This
//! works only when **all** of the following hold for the field's content:
//!
//! 1. The input is UTF-8 (always true for [`from_str`]).
//! 2. The text contains no entity references (`&`, etc.).
//! 3. The text contains no character references (`&#xNN;`).
//! 4. The text comes from a *single* `Text` or `CData` event — adjacent
//! text and CDATA segments get merged into an owned `String` and lose
//! borrow eligibility.
//!
//! Use `String` (or `Cow<'_, str>`) to handle either case.
//!
//! # Options
//!
//! Pass [`DeOptions`] to [`from_str_opts`] / [`from_bytes_opts`] to tune:
//! the underlying `ParseOptions`, the magic field names, the attribute
//! prefix, unknown-field handling, and `xsi:nil` behaviour.
use fmt;
use ;
use ParseOptions;
pub use XmlDeserializer;
// ── public entry points ──────────────────────────────────────────────────────
/// Deserialize a Rust value from an XML string. Borrows from the input
/// where possible (see the [borrowed deserialization](crate::de#borrowed-deserialization)
/// section for the precise constraints).
/// Deserialize from an XML byte slice. The bytes must be valid UTF-8.
/// Like [`from_str`], with caller-supplied [`DeOptions`].
/// Like [`from_bytes`], with caller-supplied [`DeOptions`].
// ── options ──────────────────────────────────────────────────────────────────
/// Tunables for the deserializer. Defaults match quick-xml's conventions
/// for drop-in compatibility.
// ── error type ───────────────────────────────────────────────────────────────
/// Error returned by the deserializer.