xmlity_quick_xml/
lib.rs

1#![warn(missing_docs)]
2//! # XMLity Quick XML
3//!
4//! This crate contains a reference implementation of the `xmlity` crate using the `quick-xml` crate. It is the intention to keep this crate up to date with the latest version of `quick-xml` and `xmlity`.
5#[cfg(doctest)]
6#[doc = include_str!("../../README.md")]
7struct _RootReadMeDocTests;
8
9#[cfg(doctest)]
10#[doc = include_str!("../README.md")]
11struct _ReadMeDocTests;
12
13use ::quick_xml::name::ResolveResult;
14use core::str;
15
16use xmlity::{LocalName, Prefix, QName, XmlNamespace};
17
18/// Includes the deserializer for the `quick-xml` crate.
19pub mod de;
20/// Includes the serializer for the `quick-xml` crate.
21pub mod ser;
22
23pub use de::{from_str, Deserializer};
24use quick_xml::name::{LocalName as QuickLocalName, Prefix as QuickPrefix, QName as QuickName};
25pub use ser::{to_string, to_string_pretty, Serializer};
26
27trait HasQuickXmlAlternative {
28    type QuickXmlAlternative;
29
30    fn from_quick_xml(quick_xml: Self::QuickXmlAlternative) -> Self;
31}
32
33impl<'a> HasQuickXmlAlternative for QName<'a> {
34    type QuickXmlAlternative = QuickName<'a>;
35
36    fn from_quick_xml(quick_xml: Self::QuickXmlAlternative) -> Self {
37        QName::new(
38            quick_xml.prefix().map(<&Prefix>::from_quick_xml),
39            <&LocalName>::from_quick_xml(quick_xml.local_name()),
40        )
41    }
42}
43
44impl<'a> HasQuickXmlAlternative for &'a Prefix {
45    type QuickXmlAlternative = QuickPrefix<'a>;
46    fn from_quick_xml(quick_xml: Self::QuickXmlAlternative) -> Self {
47        Prefix::new(str::from_utf8(quick_xml.into_inner()).expect("prefix should be valid utf8"))
48            .expect("A quick xml prefix should be valid")
49    }
50}
51
52impl<'a> HasQuickXmlAlternative for &'a LocalName {
53    type QuickXmlAlternative = QuickLocalName<'a>;
54    fn from_quick_xml(quick_xml: Self::QuickXmlAlternative) -> Self {
55        LocalName::new(
56            str::from_utf8(quick_xml.into_inner()).expect("local name should be valid utf8"),
57        )
58        .expect("A quick xml local name should be valid")
59    }
60}
61
62struct OwnedQuickName(Vec<u8>);
63
64impl OwnedQuickName {
65    pub fn new(name: &QName<'_>) -> Self {
66        Self(name.to_string().into_bytes())
67    }
68
69    pub fn as_ref(&self) -> QuickName<'_> {
70        QuickName(&self.0[..])
71    }
72}
73
74fn xml_namespace_from_resolve_result(value: ResolveResult<'_>) -> Option<&XmlNamespace> {
75    match value {
76        ResolveResult::Bound(namespace) => Some(
77            XmlNamespace::new(str::from_utf8(namespace.0).expect("namespace should be valid utf8"))
78                .unwrap(),
79        ),
80        _ => None,
81    }
82}
83
84/// An XML namespace declaration/singular mapping from a prefix to a namespace.
85#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
86struct XmlnsDeclaration<'a> {
87    pub prefix: &'a Prefix,
88    pub namespace: &'a XmlNamespace,
89}
90
91impl<'a> XmlnsDeclaration<'a> {
92    pub fn new(prefix: &'a Prefix, namespace: &'a XmlNamespace) -> Self {
93        Self { prefix, namespace }
94    }
95
96    /// Returns the QName for the XML namespace declaration.
97    pub fn xmlns_qname(prefix: &Prefix) -> QName<'_> {
98        if prefix.is_default() {
99            QName::new(
100                None,
101                LocalName::new("xmlns").expect("xmlns is a valid local name"),
102            )
103        } else {
104            QName::new(
105                Some(Prefix::new("xmlns").expect("xmlns is a valid prefix")),
106                <&LocalName>::from(prefix),
107            )
108        }
109    }
110}