1use core::{
9 fmt::{self, Debug},
10 str,
11};
12use std::{borrow::Cow, collections::VecDeque, fmt::Formatter, iter, ops::Deref};
13
14use crate::{
15 de,
16 ser::{self, IncludePrefix},
17 types::iterator::IteratorVisitor,
18 ExpandedName, Prefix,
19};
20
21mod deserialize;
22mod deserializer;
23mod serialize;
24mod serializer;
25
26pub fn from_value<'de, T: crate::Deserialize<'de>>(
28 value: &'de XmlValue,
29) -> Result<T, XmlValueDeserializerError> {
30 T::deserialize_seq(value)
31}
32
33pub fn to_value<T: crate::Serialize>(input: &T) -> Result<XmlValue, XmlValueSerializerError> {
35 let mut value = XmlValue::None;
36 input.serialize(&mut value)?;
37 Ok(value)
38}
39
40#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
42pub enum XmlValue {
43 Text(XmlText),
45 CData(XmlCData),
47 Element(XmlElement),
49 Seq(XmlSeq<XmlValue>),
51 PI(XmlProcessingInstruction),
53 Decl(XmlDecl),
55 Comment(XmlComment),
57 Doctype(XmlDoctype),
59 #[default]
61 None,
62}
63
64impl From<XmlText> for XmlValue {
65 fn from(value: XmlText) -> Self {
66 XmlValue::Text(value)
67 }
68}
69
70impl From<XmlCData> for XmlValue {
71 fn from(value: XmlCData) -> Self {
72 XmlValue::CData(value)
73 }
74}
75
76impl From<XmlElement> for XmlValue {
77 fn from(value: XmlElement) -> Self {
78 XmlValue::Element(value)
79 }
80}
81
82impl From<XmlSeq<XmlValue>> for XmlValue {
83 fn from(value: XmlSeq<XmlValue>) -> Self {
84 XmlValue::Seq(value)
85 }
86}
87
88impl From<XmlProcessingInstruction> for XmlValue {
89 fn from(value: XmlProcessingInstruction) -> Self {
90 XmlValue::PI(value)
91 }
92}
93impl From<XmlDecl> for XmlValue {
94 fn from(value: XmlDecl) -> Self {
95 XmlValue::Decl(value)
96 }
97}
98impl From<XmlComment> for XmlValue {
99 fn from(value: XmlComment) -> Self {
100 XmlValue::Comment(value)
101 }
102}
103impl From<XmlDoctype> for XmlValue {
104 fn from(value: XmlDoctype) -> Self {
105 XmlValue::Doctype(value)
106 }
107}
108
109#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
111#[non_exhaustive]
112pub struct XmlText(pub Vec<u8>);
113
114impl XmlText {
115 pub fn new<T: AsRef<str>>(text: T) -> Self {
117 Self(text.as_ref().as_bytes().to_vec())
118 }
119}
120
121impl Debug for XmlText {
122 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
123 f.debug_tuple("XmlText")
124 .field(&String::from_utf8_lossy(&self.0))
125 .finish()
126 }
127}
128
129impl From<String> for XmlText {
130 fn from(value: String) -> Self {
131 Self(value.into_bytes())
132 }
133}
134
135impl From<&str> for XmlText {
136 fn from(value: &str) -> Self {
137 Self(value.to_owned().into_bytes())
138 }
139}
140
141#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
143pub struct XmlCData(pub Vec<u8>);
144
145impl XmlCData {
146 pub fn new<T: Into<Vec<u8>>>(text: T) -> Self {
148 Self(text.into())
149 }
150}
151
152#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
154pub enum XmlChild {
155 Text(XmlText),
157 CData(XmlCData),
159 Element(XmlElement),
161 PI(XmlProcessingInstruction),
163 Comment(XmlComment),
165 #[default]
167 None,
168}
169
170impl From<XmlText> for XmlChild {
171 fn from(value: XmlText) -> Self {
172 XmlChild::Text(value)
173 }
174}
175
176impl From<XmlCData> for XmlChild {
177 fn from(value: XmlCData) -> Self {
178 XmlChild::CData(value)
179 }
180}
181
182impl From<XmlElement> for XmlChild {
183 fn from(value: XmlElement) -> Self {
184 XmlChild::Element(value)
185 }
186}
187
188impl From<XmlProcessingInstruction> for XmlChild {
189 fn from(value: XmlProcessingInstruction) -> Self {
190 XmlChild::PI(value)
191 }
192}
193
194impl From<XmlComment> for XmlChild {
195 fn from(value: XmlComment) -> Self {
196 XmlChild::Comment(value)
197 }
198}
199
200#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
202#[non_exhaustive]
203pub struct XmlElement {
204 pub name: ExpandedName<'static>,
206 pub attributes: VecDeque<XmlAttribute>,
208 pub children: XmlSeq<XmlChild>,
210 pub enforce_prefix: IncludePrefix,
212 pub preferred_prefix: Option<Prefix<'static>>,
214}
215
216impl XmlElement {
217 pub fn new<T: Into<ExpandedName<'static>>>(name: T) -> Self {
219 Self {
220 name: name.into(),
221 attributes: VecDeque::new(),
222 children: XmlSeq::new(),
223 enforce_prefix: IncludePrefix::default(),
224 preferred_prefix: None,
225 }
226 }
227
228 pub fn with_attribute<T: Into<XmlAttribute>>(mut self, attribute: T) -> Self {
230 self.attributes.push_back(attribute.into());
231 self
232 }
233
234 pub fn with_attributes<U: Into<XmlAttribute>, T: IntoIterator<Item = U>>(
236 mut self,
237 attributes: T,
238 ) -> Self {
239 self.attributes
240 .extend(attributes.into_iter().map(Into::into));
241 self
242 }
243
244 pub fn with_child<T: Into<XmlChild>>(mut self, child: T) -> Self {
246 self.children.values.push_back(child.into());
247 self
248 }
249
250 pub fn with_children<U: Into<XmlChild>, T: IntoIterator<Item = U>>(
252 mut self,
253 children: T,
254 ) -> Self {
255 self.children
256 .values
257 .extend(children.into_iter().map(Into::into));
258 self
259 }
260}
261
262#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
264#[non_exhaustive]
265pub struct XmlAttribute {
266 pub name: ExpandedName<'static>,
268 pub value: XmlText,
270}
271
272impl XmlAttribute {
273 pub fn new<T: Into<ExpandedName<'static>>, U: Into<XmlText>>(name: T, value: U) -> Self {
275 Self {
276 name: name.into(),
277 value: value.into(),
278 }
279 }
280}
281
282#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
284#[non_exhaustive]
285pub struct XmlSeq<T> {
286 values: VecDeque<T>,
287}
288
289impl<T> IntoIterator for XmlSeq<T> {
290 type Item = T;
291 type IntoIter = std::collections::vec_deque::IntoIter<T>;
292 fn into_iter(self) -> Self::IntoIter {
293 self.values.into_iter()
294 }
295}
296
297impl<T> FromIterator<T> for XmlSeq<T> {
298 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
299 Self {
300 values: iter.into_iter().collect(),
301 }
302 }
303}
304
305impl<T> From<VecDeque<T>> for XmlSeq<T> {
306 fn from(value: VecDeque<T>) -> Self {
307 Self::from_vec_deque(value)
308 }
309}
310
311impl<T> XmlSeq<T> {
312 pub fn new() -> Self {
314 Self::from_vec_deque(VecDeque::new())
315 }
316
317 fn from_vec_deque(values: VecDeque<T>) -> Self {
318 Self { values }
319 }
320
321 pub fn push(&mut self, value: T) {
323 self.values.push_back(value);
324 }
325}
326
327impl<T> Default for XmlSeq<T> {
328 fn default() -> Self {
329 Self::new()
330 }
331}
332
333#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
335#[non_exhaustive]
336pub struct XmlProcessingInstruction {
337 target: Vec<u8>,
338 content: Vec<u8>,
339}
340
341impl XmlProcessingInstruction {
342 pub fn new<T: Into<Vec<u8>>, U: Into<Vec<u8>>>(target: T, content: U) -> Self {
344 Self {
345 target: target.into(),
346 content: content.into(),
347 }
348 }
349}
350
351#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
353#[non_exhaustive]
354pub struct XmlDecl {
355 pub version: String,
357 pub encoding: Option<String>,
359 pub standalone: Option<String>,
361}
362
363impl XmlDecl {
364 pub fn new<T: AsRef<str>>(version: T, encoding: Option<T>, standalone: Option<T>) -> Self {
366 Self {
367 version: version.as_ref().to_string(),
368 encoding: encoding.map(|e| e.as_ref().to_string()),
369 standalone: standalone.map(|s| s.as_ref().to_string()),
370 }
371 }
372}
373
374#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
376#[non_exhaustive]
377pub struct XmlComment(pub Vec<u8>);
378
379impl XmlComment {
380 pub fn new<T: Into<Vec<u8>>>(comment: T) -> Self {
382 Self(comment.into())
383 }
384}
385
386#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
388#[non_exhaustive]
389pub struct XmlDoctype(pub Vec<u8>);
390
391impl XmlDoctype {
392 pub fn new<T: Into<Vec<u8>>>(value: T) -> Self {
394 Self(value.into())
395 }
396}
397
398#[derive(Debug, thiserror::Error)]
400pub enum XmlValueSerializerError {
401 #[error("Custom error: {0}")]
403 Custom(String),
404 #[error("Unexpected serialization: {0}")]
406 UnexpectedSerialize(ser::Unexpected),
407}
408
409impl ser::Error for XmlValueSerializerError {
410 fn unexpected_serialize(unexpected: ser::Unexpected) -> Self {
411 Self::UnexpectedSerialize(unexpected)
412 }
413
414 fn custom<T>(msg: T) -> Self
415 where
416 T: std::fmt::Display,
417 {
418 Self::Custom(msg.to_string())
419 }
420}
421
422#[derive(Debug, thiserror::Error)]
424pub enum XmlValueDeserializerError {
425 #[error("Unexpected visit: {0}")]
427 UnexpectedVisit(crate::de::Unexpected),
428 #[error("Custom error: {0}")]
430 Custom(String),
431 #[error("Wrong name: {actual:?}, expected: {expected:?}")]
433 WrongName {
434 actual: Box<ExpandedName<'static>>,
436 expected: Box<ExpandedName<'static>>,
438 },
439 #[error("Missing field: {0}")]
441 MissingField(String),
442 #[error("Unknown child")]
444 UnknownChild,
445 #[error("Invalid string")]
447 InvalidString,
448 #[error("No possible variant")]
450 NoPossibleVariant {
451 ident: String,
453 },
454 #[error("Missing data")]
456 MissingData,
457}
458
459impl de::Error for XmlValueDeserializerError {
460 fn custom<T>(msg: T) -> Self
461 where
462 T: std::fmt::Display,
463 {
464 Self::Custom(msg.to_string())
465 }
466
467 fn wrong_name(name: &ExpandedName<'_>, expected: &ExpandedName<'_>) -> Self {
468 Self::WrongName {
469 actual: Box::new(name.clone().into_owned()),
470 expected: Box::new(expected.clone().into_owned()),
471 }
472 }
473
474 fn unexpected_visit<T>(unexpected: de::Unexpected, _expected: &T) -> Self {
475 Self::UnexpectedVisit(unexpected)
476 }
477
478 fn missing_field(field: &str) -> Self {
479 Self::MissingField(field.to_string())
480 }
481
482 fn no_possible_variant(ident: &str) -> Self {
483 Self::NoPossibleVariant {
484 ident: ident.to_string(),
485 }
486 }
487
488 fn missing_data() -> Self {
489 Self::MissingData
490 }
491
492 fn unknown_child() -> Self {
493 Self::UnknownChild
494 }
495
496 fn invalid_string() -> Self {
497 Self::InvalidString
498 }
499}