1use core::{
9 fmt::{self, Debug},
10 str,
11};
12use std::{
13 borrow::Cow,
14 collections::VecDeque,
15 fmt::Formatter,
16 iter,
17 ops::{Deref, DerefMut},
18};
19
20use crate::{
21 de,
22 ser::{self, IncludePrefix},
23 types::iterator::IteratorVisitor,
24 ExpandedName, Prefix,
25};
26
27pub mod deserialize;
28mod deserializer;
29mod serialize;
30mod serializer;
31
32pub fn from_value<'de, T: crate::Deserialize<'de>>(
34 value: &'de XmlValue,
35) -> Result<T, XmlValueDeserializerError> {
36 T::deserialize_seq(value)
37}
38
39pub fn to_value<T: crate::Serialize>(input: &T) -> Result<XmlValue, XmlValueSerializerError> {
41 let mut value = XmlValue::None;
42 input.serialize(&mut value)?;
43 Ok(value)
44}
45
46#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
48pub enum XmlValue {
49 Text(XmlText),
51 CData(XmlCData),
53 Element(XmlElement),
55 Seq(XmlSeq<XmlValue>),
57 PI(XmlProcessingInstruction),
59 Decl(XmlDecl),
61 Comment(XmlComment),
63 Doctype(XmlDoctype),
65 #[default]
67 None,
68}
69
70impl From<XmlText> for XmlValue {
71 fn from(value: XmlText) -> Self {
72 XmlValue::Text(value)
73 }
74}
75
76impl From<XmlCData> for XmlValue {
77 fn from(value: XmlCData) -> Self {
78 XmlValue::CData(value)
79 }
80}
81
82impl From<XmlElement> for XmlValue {
83 fn from(value: XmlElement) -> Self {
84 XmlValue::Element(value)
85 }
86}
87
88impl From<XmlSeq<XmlValue>> for XmlValue {
89 fn from(value: XmlSeq<XmlValue>) -> Self {
90 XmlValue::Seq(value)
91 }
92}
93
94impl From<XmlProcessingInstruction> for XmlValue {
95 fn from(value: XmlProcessingInstruction) -> Self {
96 XmlValue::PI(value)
97 }
98}
99impl From<XmlDecl> for XmlValue {
100 fn from(value: XmlDecl) -> Self {
101 XmlValue::Decl(value)
102 }
103}
104impl From<XmlComment> for XmlValue {
105 fn from(value: XmlComment) -> Self {
106 XmlValue::Comment(value)
107 }
108}
109impl From<XmlDoctype> for XmlValue {
110 fn from(value: XmlDoctype) -> Self {
111 XmlValue::Doctype(value)
112 }
113}
114
115#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
116enum XmlValueWithoutSeq {
117 Text(XmlText),
119 CData(XmlCData),
121 Element(XmlElement),
123 PI(XmlProcessingInstruction),
125 Decl(XmlDecl),
127 Comment(XmlComment),
129 Doctype(XmlDoctype),
131 #[default]
133 None,
134}
135
136impl From<XmlValueWithoutSeq> for XmlValue {
137 fn from(value: XmlValueWithoutSeq) -> Self {
138 match value {
139 XmlValueWithoutSeq::Text(xml_text) => XmlValue::Text(xml_text),
140 XmlValueWithoutSeq::CData(xml_cdata) => XmlValue::CData(xml_cdata),
141 XmlValueWithoutSeq::Element(xml_element) => XmlValue::Element(xml_element),
142 XmlValueWithoutSeq::PI(xml_processing_instruction) => {
143 XmlValue::PI(xml_processing_instruction)
144 }
145 XmlValueWithoutSeq::Decl(xml_decl) => XmlValue::Decl(xml_decl),
146 XmlValueWithoutSeq::Comment(xml_comment) => XmlValue::Comment(xml_comment),
147 XmlValueWithoutSeq::Doctype(xml_doctype) => XmlValue::Doctype(xml_doctype),
148 XmlValueWithoutSeq::None => XmlValue::None,
149 }
150 }
151}
152
153#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
155#[non_exhaustive]
156pub struct XmlText(pub Vec<u8>);
157
158impl XmlText {
159 pub fn new<T: AsRef<str>>(text: T) -> Self {
161 Self(text.as_ref().as_bytes().to_vec())
162 }
163}
164
165impl Debug for XmlText {
166 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
167 f.debug_tuple("XmlText")
168 .field(&String::from_utf8_lossy(&self.0))
169 .finish()
170 }
171}
172
173impl From<String> for XmlText {
174 fn from(value: String) -> Self {
175 Self(value.into_bytes())
176 }
177}
178
179impl From<&str> for XmlText {
180 fn from(value: &str) -> Self {
181 Self(value.to_owned().into_bytes())
182 }
183}
184
185#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
187pub struct XmlCData(pub Vec<u8>);
188
189impl XmlCData {
190 pub fn new<T: Into<Vec<u8>>>(text: T) -> Self {
192 Self(text.into())
193 }
194}
195
196#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
198pub enum XmlChild {
199 Text(XmlText),
201 CData(XmlCData),
203 Element(XmlElement),
205 PI(XmlProcessingInstruction),
207 Comment(XmlComment),
209 #[default]
211 None,
212}
213
214impl From<XmlText> for XmlChild {
215 fn from(value: XmlText) -> Self {
216 XmlChild::Text(value)
217 }
218}
219
220impl From<XmlCData> for XmlChild {
221 fn from(value: XmlCData) -> Self {
222 XmlChild::CData(value)
223 }
224}
225
226impl From<XmlElement> for XmlChild {
227 fn from(value: XmlElement) -> Self {
228 XmlChild::Element(value)
229 }
230}
231
232impl From<XmlProcessingInstruction> for XmlChild {
233 fn from(value: XmlProcessingInstruction) -> Self {
234 XmlChild::PI(value)
235 }
236}
237
238impl From<XmlComment> for XmlChild {
239 fn from(value: XmlComment) -> Self {
240 XmlChild::Comment(value)
241 }
242}
243
244#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
246#[non_exhaustive]
247pub struct XmlElement {
248 pub name: ExpandedName<'static>,
250 pub attributes: VecDeque<XmlAttribute>,
252 pub children: XmlSeq<XmlChild>,
254 pub enforce_prefix: IncludePrefix,
256 pub preferred_prefix: Option<Prefix<'static>>,
258}
259
260impl XmlElement {
261 pub fn new<T: Into<ExpandedName<'static>>>(name: T) -> Self {
263 Self {
264 name: name.into(),
265 attributes: VecDeque::new(),
266 children: XmlSeq::new(),
267 enforce_prefix: IncludePrefix::default(),
268 preferred_prefix: None,
269 }
270 }
271
272 pub fn with_attribute<T: Into<XmlAttribute>>(mut self, attribute: T) -> Self {
274 self.attributes.push_back(attribute.into());
275 self
276 }
277
278 pub fn with_attributes<U: Into<XmlAttribute>, T: IntoIterator<Item = U>>(
280 mut self,
281 attributes: T,
282 ) -> Self {
283 self.attributes
284 .extend(attributes.into_iter().map(Into::into));
285 self
286 }
287
288 pub fn with_child<T: Into<XmlChild>>(mut self, child: T) -> Self {
290 self.children.values.push_back(child.into());
291 self
292 }
293
294 pub fn with_children<U: Into<XmlChild>, T: IntoIterator<Item = U>>(
296 mut self,
297 children: T,
298 ) -> Self {
299 self.children
300 .values
301 .extend(children.into_iter().map(Into::into));
302 self
303 }
304}
305
306#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
308#[non_exhaustive]
309pub struct XmlAttribute {
310 pub name: ExpandedName<'static>,
312 pub value: XmlText,
314}
315
316impl XmlAttribute {
317 pub fn new<T: Into<ExpandedName<'static>>, U: Into<XmlText>>(name: T, value: U) -> Self {
319 Self {
320 name: name.into(),
321 value: value.into(),
322 }
323 }
324}
325
326#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
328#[non_exhaustive]
329pub struct XmlSeq<T> {
330 values: VecDeque<T>,
331}
332
333impl<T> IntoIterator for XmlSeq<T> {
334 type Item = T;
335 type IntoIter = std::collections::vec_deque::IntoIter<T>;
336 fn into_iter(self) -> Self::IntoIter {
337 self.values.into_iter()
338 }
339}
340
341impl<T> FromIterator<T> for XmlSeq<T> {
342 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
343 Self {
344 values: iter.into_iter().collect(),
345 }
346 }
347}
348
349impl<T> From<VecDeque<T>> for XmlSeq<T> {
350 fn from(value: VecDeque<T>) -> Self {
351 Self::from_vec_deque(value)
352 }
353}
354
355impl<T> XmlSeq<T> {
356 pub fn new() -> Self {
358 Self::from_vec_deque(VecDeque::new())
359 }
360
361 pub fn from_vec_deque(values: VecDeque<T>) -> Self {
363 Self { values }
364 }
365
366 pub fn into_inner(self) -> VecDeque<T> {
368 self.values
369 }
370}
371
372impl Deref for XmlSeq<XmlValue> {
373 type Target = VecDeque<XmlValue>;
374
375 fn deref(&self) -> &Self::Target {
376 &self.values
377 }
378}
379
380impl DerefMut for XmlSeq<XmlValue> {
381 fn deref_mut(&mut self) -> &mut Self::Target {
382 &mut self.values
383 }
384}
385
386impl<T> Default for XmlSeq<T> {
387 fn default() -> Self {
388 Self::new()
389 }
390}
391
392#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
394#[non_exhaustive]
395pub struct XmlProcessingInstruction {
396 target: Vec<u8>,
397 content: Vec<u8>,
398}
399
400impl XmlProcessingInstruction {
401 pub fn new<T: Into<Vec<u8>>, U: Into<Vec<u8>>>(target: T, content: U) -> Self {
403 Self {
404 target: target.into(),
405 content: content.into(),
406 }
407 }
408}
409
410#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
412#[non_exhaustive]
413pub struct XmlDecl {
414 pub version: String,
416 pub encoding: Option<String>,
418 pub standalone: Option<String>,
420}
421
422impl XmlDecl {
423 pub fn new<T: AsRef<str>>(version: T, encoding: Option<T>, standalone: Option<T>) -> Self {
425 Self {
426 version: version.as_ref().to_string(),
427 encoding: encoding.map(|e| e.as_ref().to_string()),
428 standalone: standalone.map(|s| s.as_ref().to_string()),
429 }
430 }
431}
432
433#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
435#[non_exhaustive]
436pub struct XmlComment(pub Vec<u8>);
437
438impl XmlComment {
439 pub fn new<T: Into<Vec<u8>>>(comment: T) -> Self {
441 Self(comment.into())
442 }
443}
444
445#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
447#[non_exhaustive]
448pub struct XmlDoctype(pub Vec<u8>);
449
450impl XmlDoctype {
451 pub fn new<T: Into<Vec<u8>>>(value: T) -> Self {
453 Self(value.into())
454 }
455}
456
457#[derive(Debug, thiserror::Error)]
459pub enum XmlValueSerializerError {
460 #[error("Custom error: {0}")]
462 Custom(String),
463 #[error("Unexpected serialization: {0}")]
465 UnexpectedSerialize(ser::Unexpected),
466}
467
468impl ser::Error for XmlValueSerializerError {
469 fn unexpected_serialize(unexpected: ser::Unexpected) -> Self {
470 Self::UnexpectedSerialize(unexpected)
471 }
472
473 fn custom<T>(msg: T) -> Self
474 where
475 T: std::fmt::Display,
476 {
477 Self::Custom(msg.to_string())
478 }
479}
480
481#[derive(Debug, thiserror::Error)]
483pub enum XmlValueDeserializerError {
484 #[error("Unexpected visit: {0}")]
486 UnexpectedVisit(crate::de::Unexpected),
487 #[error("Custom error: {0}")]
489 Custom(String),
490 #[error("Wrong name: {actual:?}, expected: {expected:?}")]
492 WrongName {
493 actual: Box<ExpandedName<'static>>,
495 expected: Box<ExpandedName<'static>>,
497 },
498 #[error("Missing field: {0}")]
500 MissingField(String),
501 #[error("Unknown child")]
503 UnknownChild,
504 #[error("Invalid string")]
506 InvalidString,
507 #[error("No possible variant")]
509 NoPossibleVariant {
510 ident: String,
512 },
513 #[error("Missing data")]
515 MissingData,
516}
517
518impl de::Error for XmlValueDeserializerError {
519 fn custom<T>(msg: T) -> Self
520 where
521 T: std::fmt::Display,
522 {
523 Self::Custom(msg.to_string())
524 }
525
526 fn wrong_name(name: &ExpandedName<'_>, expected: &ExpandedName<'_>) -> Self {
527 Self::WrongName {
528 actual: Box::new(name.clone().into_owned()),
529 expected: Box::new(expected.clone().into_owned()),
530 }
531 }
532
533 fn unexpected_visit<T>(unexpected: de::Unexpected, _expected: &T) -> Self {
534 Self::UnexpectedVisit(unexpected)
535 }
536
537 fn missing_field(field: &str) -> Self {
538 Self::MissingField(field.to_string())
539 }
540
541 fn no_possible_variant(ident: &str) -> Self {
542 Self::NoPossibleVariant {
543 ident: ident.to_string(),
544 }
545 }
546
547 fn missing_data() -> Self {
548 Self::MissingData
549 }
550
551 fn unknown_child() -> Self {
552 Self::UnknownChild
553 }
554
555 fn invalid_string() -> Self {
556 Self::InvalidString
557 }
558}