quick_xml/
name.rs

1//! Module for handling names according to the W3C [Namespaces in XML 1.1 (Second Edition)][spec]
2//! specification
3//!
4//! [spec]: https://www.w3.org/TR/xml-names11
5
6use crate::events::attributes::Attribute;
7use crate::events::{BytesStart, Event};
8use crate::utils::write_byte_string;
9use memchr::memchr;
10use std::fmt::{self, Debug, Formatter};
11use std::iter::FusedIterator;
12
13/// Some namespace was invalid
14#[derive(Debug, Clone, PartialEq, Eq)]
15pub enum NamespaceError {
16    /// Specified namespace prefix is unknown, cannot resolve namespace for it
17    UnknownPrefix(Vec<u8>),
18    /// Attempts to bind the `xml` prefix to something other than `http://www.w3.org/XML/1998/namespace`.
19    ///
20    /// `xml` prefix can be bound only to `http://www.w3.org/XML/1998/namespace`.
21    ///
22    /// Contains the namespace to which `xml` tried to be bound.
23    InvalidXmlPrefixBind(Vec<u8>),
24    /// Attempts to bind the `xmlns` prefix.
25    ///
26    /// `xmlns` prefix is always bound to `http://www.w3.org/2000/xmlns/` and cannot be bound
27    /// to any other namespace or even to `http://www.w3.org/2000/xmlns/`.
28    ///
29    /// Contains the namespace to which `xmlns` tried to be bound.
30    InvalidXmlnsPrefixBind(Vec<u8>),
31    /// Attempts to bind some prefix (except `xml`) to `http://www.w3.org/XML/1998/namespace`.
32    ///
33    /// Only `xml` prefix can be bound to `http://www.w3.org/XML/1998/namespace`.
34    ///
35    /// Contains the prefix that is tried to be bound.
36    InvalidPrefixForXml(Vec<u8>),
37    /// Attempts to bind some prefix to `http://www.w3.org/2000/xmlns/`.
38    ///
39    /// `http://www.w3.org/2000/xmlns/` cannot be bound to any prefix, even to `xmlns`.
40    ///
41    /// Contains the prefix that is tried to be bound.
42    InvalidPrefixForXmlns(Vec<u8>),
43}
44
45impl fmt::Display for NamespaceError {
46    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
47        match self {
48            Self::UnknownPrefix(prefix) => {
49                f.write_str("unknown namespace prefix '")?;
50                write_byte_string(f, prefix)?;
51                f.write_str("'")
52            }
53            Self::InvalidXmlPrefixBind(namespace) => {
54                f.write_str("the namespace prefix 'xml' cannot be bound to '")?;
55                write_byte_string(f, namespace)?;
56                f.write_str("'")
57            }
58            Self::InvalidXmlnsPrefixBind(namespace) => {
59                f.write_str("the namespace prefix 'xmlns' cannot be bound to '")?;
60                write_byte_string(f, namespace)?;
61                f.write_str("'")
62            }
63            Self::InvalidPrefixForXml(prefix) => {
64                f.write_str("the namespace prefix '")?;
65                write_byte_string(f, prefix)?;
66                f.write_str("' cannot be bound to 'http://www.w3.org/XML/1998/namespace'")
67            }
68            Self::InvalidPrefixForXmlns(prefix) => {
69                f.write_str("the namespace prefix '")?;
70                write_byte_string(f, prefix)?;
71                f.write_str("' cannot be bound to 'http://www.w3.org/2000/xmlns/'")
72            }
73        }
74    }
75}
76
77impl std::error::Error for NamespaceError {}
78
79////////////////////////////////////////////////////////////////////////////////////////////////////
80
81/// A [qualified name] of an element or an attribute, including an optional
82/// namespace [prefix](Prefix) and a [local name](LocalName).
83///
84/// [qualified name]: https://www.w3.org/TR/xml-names11/#dt-qualname
85#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
86#[cfg_attr(feature = "serde-types", derive(serde::Deserialize, serde::Serialize))]
87pub struct QName<'a>(pub &'a [u8]);
88impl<'a> QName<'a> {
89    /// Converts this name to an internal slice representation.
90    #[inline(always)]
91    pub const fn into_inner(self) -> &'a [u8] {
92        self.0
93    }
94
95    /// Returns local part of this qualified name.
96    ///
97    /// All content up to and including the first `:` character is removed from
98    /// the tag name.
99    ///
100    /// # Examples
101    ///
102    /// ```
103    /// # use quick_xml::name::QName;
104    /// let simple = QName(b"simple-name");
105    /// assert_eq!(simple.local_name().as_ref(), b"simple-name");
106    ///
107    /// let qname = QName(b"namespace:simple-name");
108    /// assert_eq!(qname.local_name().as_ref(), b"simple-name");
109    /// ```
110    pub fn local_name(&self) -> LocalName<'a> {
111        LocalName(self.index().map_or(self.0, |i| &self.0[i + 1..]))
112    }
113
114    /// Returns namespace part of this qualified name or `None` if namespace part
115    /// is not defined (symbol `':'` not found).
116    ///
117    /// # Examples
118    ///
119    /// ```
120    /// # use std::convert::AsRef;
121    /// # use quick_xml::name::QName;
122    /// let simple = QName(b"simple-name");
123    /// assert_eq!(simple.prefix(), None);
124    ///
125    /// let qname = QName(b"prefix:simple-name");
126    /// assert_eq!(qname.prefix().as_ref().map(|n| n.as_ref()), Some(b"prefix".as_ref()));
127    /// ```
128    pub fn prefix(&self) -> Option<Prefix<'a>> {
129        self.index().map(|i| Prefix(&self.0[..i]))
130    }
131
132    /// The same as `(qname.local_name(), qname.prefix())`, but does only one
133    /// lookup for a `':'` symbol.
134    pub fn decompose(&self) -> (LocalName<'a>, Option<Prefix<'a>>) {
135        match self.index() {
136            None => (LocalName(self.0), None),
137            Some(i) => (LocalName(&self.0[i + 1..]), Some(Prefix(&self.0[..i]))),
138        }
139    }
140
141    /// If that `QName` represents `"xmlns"` series of names, returns `Some`,
142    /// otherwise `None` is returned.
143    ///
144    /// # Examples
145    ///
146    /// ```
147    /// # use quick_xml::name::{QName, PrefixDeclaration};
148    /// let qname = QName(b"xmlns");
149    /// assert_eq!(qname.as_namespace_binding(), Some(PrefixDeclaration::Default));
150    ///
151    /// let qname = QName(b"xmlns:prefix");
152    /// assert_eq!(qname.as_namespace_binding(), Some(PrefixDeclaration::Named(b"prefix")));
153    ///
154    /// // Be aware that this method does not check the validity of the prefix - it can be empty!
155    /// let qname = QName(b"xmlns:");
156    /// assert_eq!(qname.as_namespace_binding(), Some(PrefixDeclaration::Named(b"")));
157    ///
158    /// let qname = QName(b"other-name");
159    /// assert_eq!(qname.as_namespace_binding(), None);
160    ///
161    /// // https://www.w3.org/TR/xml-names11/#xmlReserved
162    /// let qname = QName(b"xmlns-reserved-name");
163    /// assert_eq!(qname.as_namespace_binding(), None);
164    /// ```
165    pub fn as_namespace_binding(&self) -> Option<PrefixDeclaration<'a>> {
166        if self.0.starts_with(b"xmlns") {
167            return match self.0.get(5) {
168                None => Some(PrefixDeclaration::Default),
169                Some(&b':') => Some(PrefixDeclaration::Named(&self.0[6..])),
170                _ => None,
171            };
172        }
173        None
174    }
175
176    /// Returns the index in the name where prefix ended
177    #[inline(always)]
178    fn index(&self) -> Option<usize> {
179        memchr(b':', self.0)
180    }
181}
182impl<'a> Debug for QName<'a> {
183    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
184        write!(f, "QName(")?;
185        write_byte_string(f, self.0)?;
186        write!(f, ")")
187    }
188}
189impl<'a> AsRef<[u8]> for QName<'a> {
190    #[inline]
191    fn as_ref(&self) -> &[u8] {
192        self.0
193    }
194}
195
196////////////////////////////////////////////////////////////////////////////////////////////////////
197
198/// A [local (unqualified) name] of an element or an attribute, i.e. a name
199/// without [prefix](Prefix).
200///
201/// [local (unqualified) name]: https://www.w3.org/TR/xml-names11/#dt-localname
202#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
203#[cfg_attr(feature = "serde-types", derive(serde::Deserialize, serde::Serialize))]
204pub struct LocalName<'a>(pub(crate) &'a [u8]);
205impl<'a> LocalName<'a> {
206    /// Converts this name to an internal slice representation.
207    #[inline(always)]
208    pub const fn into_inner(self) -> &'a [u8] {
209        self.0
210    }
211}
212impl<'a> Debug for LocalName<'a> {
213    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
214        write!(f, "LocalName(")?;
215        write_byte_string(f, self.0)?;
216        write!(f, ")")
217    }
218}
219impl<'a> AsRef<[u8]> for LocalName<'a> {
220    #[inline]
221    fn as_ref(&self) -> &[u8] {
222        self.0
223    }
224}
225impl<'a> From<QName<'a>> for LocalName<'a> {
226    /// Creates `LocalName` from a [`QName`]
227    ///
228    /// # Examples
229    ///
230    /// ```
231    /// # use quick_xml::name::{LocalName, QName};
232    ///
233    /// let local: LocalName = QName(b"unprefixed").into();
234    /// assert_eq!(local.as_ref(), b"unprefixed");
235    ///
236    /// let local: LocalName = QName(b"some:prefix").into();
237    /// assert_eq!(local.as_ref(), b"prefix");
238    /// ```
239    #[inline]
240    fn from(name: QName<'a>) -> Self {
241        Self(name.index().map_or(name.0, |i| &name.0[i + 1..]))
242    }
243}
244
245////////////////////////////////////////////////////////////////////////////////////////////////////
246
247/// A [namespace prefix] part of the [qualified name](QName) of an element tag
248/// or an attribute: a `prefix` in `<prefix:local-element-name>` or
249/// `prefix:local-attribute-name="attribute value"`.
250///
251/// [namespace prefix]: https://www.w3.org/TR/xml-names11/#dt-prefix
252#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
253#[cfg_attr(feature = "serde-types", derive(serde::Deserialize, serde::Serialize))]
254pub struct Prefix<'a>(&'a [u8]);
255impl<'a> Prefix<'a> {
256    /// Extracts internal slice
257    #[inline(always)]
258    pub const fn into_inner(self) -> &'a [u8] {
259        self.0
260    }
261
262    /// Checks if this prefix is a special prefix `xml`.
263    #[inline(always)]
264    pub const fn is_xml(&self) -> bool {
265        matches!(self.0, b"xml")
266    }
267
268    /// Checks if this prefix is a special prefix `xmlns`.
269    #[inline(always)]
270    pub const fn is_xmlns(&self) -> bool {
271        matches!(self.0, b"xmlns")
272    }
273}
274impl<'a> Debug for Prefix<'a> {
275    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
276        write!(f, "Prefix(")?;
277        write_byte_string(f, self.0)?;
278        write!(f, ")")
279    }
280}
281impl<'a> AsRef<[u8]> for Prefix<'a> {
282    #[inline]
283    fn as_ref(&self) -> &[u8] {
284        self.0
285    }
286}
287
288////////////////////////////////////////////////////////////////////////////////////////////////////
289
290/// A namespace prefix declaration, `xmlns` or `xmlns:<name>`, as defined in
291/// [XML Schema specification](https://www.w3.org/TR/xml-names11/#ns-decl)
292#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
293pub enum PrefixDeclaration<'a> {
294    /// XML attribute binds a default namespace. Corresponds to `xmlns` in `xmlns="..."`
295    Default,
296    /// XML attribute binds a specified prefix to a namespace. Corresponds to a
297    /// `prefix` in `xmlns:prefix="..."`, which is stored as payload of this variant.
298    Named(&'a [u8]),
299}
300impl<'a> Debug for PrefixDeclaration<'a> {
301    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
302        match self {
303            Self::Default => f.write_str("PrefixDeclaration::Default"),
304            Self::Named(prefix) => {
305                f.write_str("PrefixDeclaration::Named(")?;
306                write_byte_string(f, prefix)?;
307                f.write_str(")")
308            }
309        }
310    }
311}
312
313////////////////////////////////////////////////////////////////////////////////////////////////////
314
315/// A [namespace name] that is declared in a `xmlns[:prefix]="namespace name"`.
316///
317/// [namespace name]: https://www.w3.org/TR/xml-names11/#dt-NSName
318#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
319#[cfg_attr(feature = "serde-types", derive(serde::Deserialize, serde::Serialize))]
320pub struct Namespace<'a>(pub &'a [u8]);
321impl<'a> Namespace<'a> {
322    /// Converts this namespace to an internal slice representation.
323    ///
324    /// This is [non-normalized] attribute value, i.e. any entity references is
325    /// not expanded and space characters are not removed. This means, that
326    /// different byte slices, returned from this method, can represent the same
327    /// namespace and would be treated by parser as identical.
328    ///
329    /// For example, if the entity **eacute** has been defined to be **é**,
330    /// the empty tags below all contain namespace declarations binding the
331    /// prefix `p` to the same [IRI reference], `http://example.org/rosé`.
332    ///
333    /// ```xml
334    /// <p:foo xmlns:p="http://example.org/rosé" />
335    /// <p:foo xmlns:p="http://example.org/ros&#xe9;" />
336    /// <p:foo xmlns:p="http://example.org/ros&#xE9;" />
337    /// <p:foo xmlns:p="http://example.org/ros&#233;" />
338    /// <p:foo xmlns:p="http://example.org/ros&eacute;" />
339    /// ```
340    ///
341    /// This is because XML entity references are expanded during attribute value
342    /// normalization.
343    ///
344    /// [non-normalized]: https://www.w3.org/TR/xml11/#AVNormalize
345    /// [IRI reference]: https://datatracker.ietf.org/doc/html/rfc3987
346    #[inline(always)]
347    pub const fn into_inner(self) -> &'a [u8] {
348        self.0
349    }
350    //TODO: implement value normalization and use it when comparing namespaces
351}
352impl<'a> Debug for Namespace<'a> {
353    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
354        write!(f, "Namespace(")?;
355        write_byte_string(f, self.0)?;
356        write!(f, ")")
357    }
358}
359impl<'a> AsRef<[u8]> for Namespace<'a> {
360    #[inline]
361    fn as_ref(&self) -> &[u8] {
362        self.0
363    }
364}
365
366////////////////////////////////////////////////////////////////////////////////////////////////////
367
368/// Result of [prefix] resolution which creates by [`NamespaceResolver::resolve`], [`NsReader::resolve_attribute`],
369/// [`NsReader::resolve_element`], [`NsReader::read_resolved_event`] and
370/// [`NsReader::read_resolved_event_into`] methods.
371///
372/// [prefix]: Prefix
373/// [`NsReader::resolve_attribute`]: crate::reader::NsReader::resolve_attribute
374/// [`NsReader::resolve_element`]: crate::reader::NsReader::resolve_element
375/// [`NsReader::read_resolved_event`]: crate::reader::NsReader::read_resolved_event
376/// [`NsReader::read_resolved_event_into`]: crate::reader::NsReader::read_resolved_event_into
377#[derive(Clone, PartialEq, Eq, Hash)]
378pub enum ResolveResult<'ns> {
379    /// Qualified name does not contain prefix, and resolver does not define
380    /// default namespace, so name is not bound to any namespace
381    Unbound,
382    /// [`Prefix`] resolved to the specified namespace
383    Bound(Namespace<'ns>),
384    /// Specified prefix was not found in scope
385    Unknown(Vec<u8>),
386}
387impl<'ns> Debug for ResolveResult<'ns> {
388    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
389        match self {
390            Self::Unbound => write!(f, "Unbound"),
391            Self::Bound(ns) => write!(f, "Bound({:?})", ns),
392            Self::Unknown(p) => {
393                write!(f, "Unknown(")?;
394                write_byte_string(f, p)?;
395                write!(f, ")")
396            }
397        }
398    }
399}
400
401impl<'ns> TryFrom<ResolveResult<'ns>> for Option<Namespace<'ns>> {
402    type Error = NamespaceError;
403
404    /// Try to convert this result to an optional namespace and returns
405    /// [`NamespaceError::UnknownPrefix`] if this result represents unknown prefix
406    fn try_from(result: ResolveResult<'ns>) -> Result<Self, NamespaceError> {
407        use ResolveResult::*;
408
409        match result {
410            Unbound => Ok(None),
411            Bound(ns) => Ok(Some(ns)),
412            Unknown(p) => Err(NamespaceError::UnknownPrefix(p)),
413        }
414    }
415}
416
417////////////////////////////////////////////////////////////////////////////////////////////////////
418
419/// An entry that contains index into the buffer with namespace bindings.
420///
421/// Defines a mapping from *[namespace prefix]* to *[namespace name]*.
422/// If prefix is empty, defines a *default namespace* binding that applies to
423/// unprefixed element names (unprefixed attribute names do not bind to any
424/// namespace and they processing is dependent on the element in which their
425/// defined).
426///
427/// [namespace prefix]: https://www.w3.org/TR/xml-names11/#dt-prefix
428/// [namespace name]: https://www.w3.org/TR/xml-names11/#dt-NSName
429#[derive(Debug, Clone)]
430struct NamespaceBinding {
431    /// Index of the namespace in the buffer
432    start: usize,
433    /// Length of the prefix
434    /// * if greater than zero, then binds this namespace to the slice
435    ///   `[start..start + prefix_len]` in the buffer.
436    /// * else defines the current default namespace.
437    prefix_len: usize,
438    /// The length of a namespace name (the URI) of this namespace declaration.
439    /// Name started just after prefix and extend for `value_len` bytes.
440    ///
441    /// The XML standard [specifies] that an empty namespace value 'removes' a namespace declaration
442    /// for the extent of its scope. For prefix declarations that's not very interesting, but it is
443    /// vital for default namespace declarations. With `xmlns=""` you can revert back to the default
444    /// behaviour of leaving unqualified element names unqualified.
445    ///
446    /// [specifies]: https://www.w3.org/TR/xml-names11/#scoping
447    value_len: usize,
448    /// Level of nesting at which this namespace was declared. The declaring element is included,
449    /// i.e., a declaration on the document root has `level = 1`.
450    /// This is used to pop the namespace when the element gets closed.
451    level: u16,
452}
453
454impl NamespaceBinding {
455    /// Get the namespace prefix, bound to this namespace declaration, or `None`,
456    /// if this declaration is for default namespace (`xmlns="..."`).
457    #[inline]
458    fn prefix<'b>(&self, ns_buffer: &'b [u8]) -> Option<Prefix<'b>> {
459        if self.prefix_len == 0 {
460            None
461        } else {
462            Some(Prefix(&ns_buffer[self.start..self.start + self.prefix_len]))
463        }
464    }
465
466    /// Gets the namespace name (the URI) slice out of namespace buffer
467    ///
468    /// Returns `None` if namespace for this prefix was explicitly removed from
469    /// scope, using `xmlns[:prefix]=""`
470    #[inline]
471    fn namespace<'ns>(&self, buffer: &'ns [u8]) -> ResolveResult<'ns> {
472        if self.value_len == 0 {
473            ResolveResult::Unbound
474        } else {
475            let start = self.start + self.prefix_len;
476            ResolveResult::Bound(Namespace(&buffer[start..start + self.value_len]))
477        }
478    }
479}
480
481/// A storage for currently defined namespace bindings, which is used to resolve
482/// prefixes into namespaces.
483///
484/// Holds all internal logic to push/pop namespaces with their levels.
485#[derive(Debug, Clone)]
486pub struct NamespaceResolver {
487    /// Buffer that contains names of namespace prefixes (the part between `xmlns:`
488    /// and an `=`) and namespace values.
489    buffer: Vec<u8>,
490    /// A stack of namespace bindings to prefixes that currently in scope
491    bindings: Vec<NamespaceBinding>,
492    /// The number of open tags at the moment. We need to keep track of this to know which namespace
493    /// declarations to remove when we encounter an `End` event.
494    nesting_level: u16,
495}
496
497/// That constant define the one of [reserved namespaces] for the xml standard.
498///
499/// The prefix `xml` is by definition bound to the namespace name
500/// `http://www.w3.org/XML/1998/namespace`. It may, but need not, be declared, and must not be
501/// undeclared or bound to any other namespace name. Other prefixes must not be bound to this
502/// namespace name, and it must not be declared as the default namespace.
503///
504/// [reserved namespaces]: https://www.w3.org/TR/xml-names11/#xmlReserved
505const RESERVED_NAMESPACE_XML: (Prefix, Namespace) = (
506    Prefix(b"xml"),
507    Namespace(b"http://www.w3.org/XML/1998/namespace"),
508);
509/// That constant define the one of [reserved namespaces] for the xml standard.
510///
511/// The prefix `xmlns` is used only to declare namespace bindings and is by definition bound
512/// to the namespace name `http://www.w3.org/2000/xmlns/`. It must not be declared or
513/// undeclared. Other prefixes must not be bound to this namespace name, and it must not be
514/// declared as the default namespace. Element names must not have the prefix `xmlns`.
515///
516/// [reserved namespaces]: https://www.w3.org/TR/xml-names11/#xmlReserved
517const RESERVED_NAMESPACE_XMLNS: (Prefix, Namespace) = (
518    Prefix(b"xmlns"),
519    Namespace(b"http://www.w3.org/2000/xmlns/"),
520);
521
522impl Default for NamespaceResolver {
523    fn default() -> Self {
524        let mut buffer = Vec::new();
525        let mut bindings = Vec::new();
526        for ent in &[RESERVED_NAMESPACE_XML, RESERVED_NAMESPACE_XMLNS] {
527            let prefix = ent.0.into_inner();
528            let uri = ent.1.into_inner();
529            bindings.push(NamespaceBinding {
530                start: buffer.len(),
531                prefix_len: prefix.len(),
532                value_len: uri.len(),
533                level: 0,
534            });
535            buffer.extend(prefix);
536            buffer.extend(uri);
537        }
538
539        Self {
540            buffer,
541            bindings,
542            nesting_level: 0,
543        }
544    }
545}
546
547impl NamespaceResolver {
548    /// Adds new binding of prefix to namespace, returns the result of operation.
549    ///
550    /// Binding will be added on current nesting level and will be removed, when
551    /// level will be [popped out].
552    ///
553    /// The operation may fail if you try to (re-)declare reserved prefixes `xml` and `xmlns`.
554    ///
555    /// Note, that method does not check if namespace was already added on that level.
556    /// Use `resolver.bindings_of(resolver.level()).any()` if you want to check that.
557    /// New definition will be added and replace the old.
558    ///
559    /// Implementation detail: memory occupied by old binding of that level still will be used.
560    ///
561    /// ```
562    /// # use pretty_assertions::assert_eq;
563    /// # use quick_xml::name::{Namespace, NamespaceResolver, PrefixDeclaration, QName, ResolveResult};
564    /// #
565    /// let mut resolver = NamespaceResolver::default();
566    /// // names without prefix are unbound by default
567    /// assert_eq!(
568    ///     resolver.resolve_element(QName(b"name")).0,
569    ///     ResolveResult::Unbound,
570    /// );
571    /// // names with undeclared prefix are unknown
572    /// assert_eq!(
573    ///     resolver.resolve_element(QName(b"ns:name")).0,
574    ///     ResolveResult::Unknown(b"ns".to_vec()),
575    /// );
576    ///
577    /// resolver.add(PrefixDeclaration::Default, Namespace(b"example.com"));
578    /// resolver.add(PrefixDeclaration::Named(b"ns"), Namespace(b"my:namespace"));
579    ///
580    /// assert_eq!(
581    ///     resolver.resolve_element(QName(b"name")).0,
582    ///     ResolveResult::Bound(Namespace(b"example.com")),
583    /// );
584    /// assert_eq!(
585    ///     resolver.resolve_element(QName(b"ns:name")).0,
586    ///     ResolveResult::Bound(Namespace(b"my:namespace")),
587    /// );
588    ///
589    /// // adding empty namespace clears the binding
590    /// resolver.add(PrefixDeclaration::Default, Namespace(b""));
591    /// resolver.add(PrefixDeclaration::Named(b"ns"), Namespace(b""));
592    ///
593    /// assert_eq!(
594    ///     resolver.resolve_element(QName(b"name")).0,
595    ///     ResolveResult::Unbound,
596    /// );
597    /// assert_eq!(
598    ///     resolver.resolve_element(QName(b"ns:name")).0,
599    ///     ResolveResult::Unknown(b"ns".to_vec()),
600    /// );
601    /// ```
602    /// [popped out]: Self::pop
603    pub fn add(
604        &mut self,
605        prefix: PrefixDeclaration,
606        namespace: Namespace,
607    ) -> Result<(), NamespaceError> {
608        let level = self.nesting_level;
609        match prefix {
610            PrefixDeclaration::Default => {
611                let start = self.buffer.len();
612                self.buffer.extend_from_slice(&namespace.0);
613                self.bindings.push(NamespaceBinding {
614                    start,
615                    prefix_len: 0,
616                    value_len: namespace.0.len(),
617                    level,
618                });
619            }
620            PrefixDeclaration::Named(b"xml") => {
621                if namespace != RESERVED_NAMESPACE_XML.1 {
622                    // error, `xml` prefix explicitly set to different value
623                    return Err(NamespaceError::InvalidXmlPrefixBind(namespace.0.to_vec()));
624                }
625                // don't add another NamespaceEntry for the `xml` namespace prefix
626            }
627            PrefixDeclaration::Named(b"xmlns") => {
628                // error, `xmlns` prefix explicitly set
629                return Err(NamespaceError::InvalidXmlnsPrefixBind(namespace.0.to_vec()));
630            }
631            PrefixDeclaration::Named(prefix) => {
632                // error, non-`xml` prefix set to xml uri
633                if namespace == RESERVED_NAMESPACE_XML.1 {
634                    return Err(NamespaceError::InvalidPrefixForXml(prefix.to_vec()));
635                } else
636                // error, non-`xmlns` prefix set to xmlns uri
637                if namespace == RESERVED_NAMESPACE_XMLNS.1 {
638                    return Err(NamespaceError::InvalidPrefixForXmlns(prefix.to_vec()));
639                }
640
641                let start = self.buffer.len();
642                self.buffer.extend_from_slice(prefix);
643                self.buffer.extend_from_slice(&namespace.0);
644                self.bindings.push(NamespaceBinding {
645                    start,
646                    prefix_len: prefix.len(),
647                    value_len: namespace.0.len(),
648                    level,
649                });
650            }
651        }
652        Ok(())
653    }
654
655    /// Begins a new scope and add to it all [namespace bindings] that found in
656    /// the specified start element.
657    ///
658    /// [namespace bindings]: https://www.w3.org/TR/xml-names11/#dt-NSDecl
659    pub fn push(&mut self, start: &BytesStart) -> Result<(), NamespaceError> {
660        self.nesting_level += 1;
661        // adds new namespaces for attributes starting with 'xmlns:' and for the 'xmlns'
662        // (default namespace) attribute.
663        for a in start.attributes().with_checks(false) {
664            if let Ok(Attribute { key: k, value: v }) = a {
665                match k.as_namespace_binding() {
666                    Some(prefix) => self.add(prefix, Namespace(&v))?,
667                    None => {}
668                }
669            } else {
670                break;
671            }
672        }
673        Ok(())
674    }
675
676    /// Ends a top-most scope by popping all [namespace bindings], that was added by
677    /// last call to [`Self::push()`] and [`Self::add()`].
678    ///
679    /// [namespace bindings]: https://www.w3.org/TR/xml-names11/#dt-NSDecl
680    pub fn pop(&mut self) {
681        self.nesting_level = self.nesting_level.saturating_sub(1);
682        let current_level = self.nesting_level;
683        // from the back (most deeply nested scope), look for the first scope that is still valid
684        match self.bindings.iter().rposition(|n| n.level <= current_level) {
685            // none of the namespaces are valid, remove all of them
686            None => {
687                self.buffer.clear();
688                self.bindings.clear();
689            }
690            // drop all namespaces past the last valid namespace
691            Some(last_valid_pos) => {
692                if let Some(len) = self.bindings.get(last_valid_pos + 1).map(|n| n.start) {
693                    self.buffer.truncate(len);
694                    self.bindings.truncate(last_valid_pos + 1);
695                }
696            }
697        }
698    }
699
700    /// Resolves a potentially qualified **element name** or **attribute name**
701    /// into _(namespace name, local name)_.
702    ///
703    /// _Qualified_ names have the form `local-name` or `prefix:local-name` where the `prefix`
704    /// is defined on any containing XML element via `xmlns:prefix="the:namespace:uri"`.
705    /// The namespace prefix can be defined on the same element as the name in question.
706    ///
707    /// The method returns following results depending on the `name` shape, `attribute` flag
708    /// and the presence of the default namespace on element or any of its parents:
709    ///
710    /// |use_default|`xmlns="..."`|QName              |ResolveResult          |LocalName
711    /// |-----------|-------------|-------------------|-----------------------|------------
712    /// |`false`    |_(any)_      |`local-name`       |[`Unbound`]            |`local-name`
713    /// |`false`    |_(any)_      |`prefix:local-name`|[`Bound`] / [`Unknown`]|`local-name`
714    /// |`true`     |Not defined  |`local-name`       |[`Unbound`]            |`local-name`
715    /// |`true`     |Defined      |`local-name`       |[`Bound`] (to `xmlns`) |`local-name`
716    /// |`true`     |_(any)_      |`prefix:local-name`|[`Bound`] / [`Unknown`]|`local-name`
717    ///
718    /// # Parameters
719    /// - `name`: probably qualified name to resolve;
720    /// - `use_default`: whether to try to translate `None` prefix to the currently default namespace
721    ///   (bound using `xmlns="default namespace"`) or return [`ResolveResult::Unbound`].
722    ///   For attribute names this should be set to `false` and for element names to `true`.
723    ///
724    /// # Lifetimes
725    ///
726    /// - `'n`: lifetime of a name. Returned local name will be bound to the same
727    ///   lifetime as the name in question.
728    /// - returned namespace name will be bound to the resolver itself
729    ///
730    /// [`Bound`]: ResolveResult::Bound
731    /// [`Unbound`]: ResolveResult::Unbound
732    /// [`Unknown`]: ResolveResult::Unknown
733    #[inline]
734    pub fn resolve<'n>(
735        &self,
736        name: QName<'n>,
737        use_default: bool,
738    ) -> (ResolveResult<'_>, LocalName<'n>) {
739        let (local_name, prefix) = name.decompose();
740        (self.resolve_prefix(prefix, use_default), local_name)
741    }
742
743    /// Convenient method to call `resolve(name, true)`. May be used to clearly
744    /// express that we want to resolve an element name, and not an attribute name.
745    #[inline]
746    pub fn resolve_element<'n>(&self, name: QName<'n>) -> (ResolveResult<'_>, LocalName<'n>) {
747        self.resolve(name, true)
748    }
749
750    /// Convenient method to call `resolve(name, false)`. May be used to clearly
751    /// express that we want to resolve an attribute name, and not an element name.
752    #[inline]
753    pub fn resolve_attribute<'n>(&self, name: QName<'n>) -> (ResolveResult<'_>, LocalName<'n>) {
754        self.resolve(name, false)
755    }
756
757    /// Finds a [namespace name] for a given event, if applicable.
758    ///
759    /// Namespace is resolved only for [`Start`], [`Empty`] and [`End`] events.
760    /// For all other events the concept of namespace is not defined, so
761    /// a [`ResolveResult::Unbound`] is returned.
762    ///
763    /// # Examples
764    ///
765    /// ```
766    /// # use pretty_assertions::assert_eq;
767    /// use quick_xml::events::Event;
768    /// use quick_xml::name::{Namespace, QName, ResolveResult::*};
769    /// use quick_xml::reader::NsReader;
770    ///
771    /// let mut reader = NsReader::from_str(r#"
772    ///     <x:tag1 xmlns:x="www.xxxx" xmlns:y="www.yyyy" att1 = "test">
773    ///        <y:tag2><!--Test comment-->Test</y:tag2>
774    ///        <y:tag2>Test 2</y:tag2>
775    ///     </x:tag1>
776    /// "#);
777    /// reader.config_mut().trim_text(true);
778    ///
779    /// let mut count = 0;
780    /// let mut txt = Vec::new();
781    /// loop {
782    ///     let event = reader.read_event().unwrap();
783    ///     match reader.resolver().resolve_event(event) {
784    ///         (Bound(Namespace(b"www.xxxx")), Event::Start(e)) => {
785    ///             count += 1;
786    ///             assert_eq!(e.local_name(), QName(b"tag1").into());
787    ///         }
788    ///         (Bound(Namespace(b"www.yyyy")), Event::Start(e)) => {
789    ///             count += 1;
790    ///             assert_eq!(e.local_name(), QName(b"tag2").into());
791    ///         }
792    ///         (_, Event::Start(_)) => unreachable!(),
793    ///
794    ///         (_, Event::Text(e)) => {
795    ///             txt.push(e.decode().unwrap().into_owned())
796    ///         }
797    ///         (_, Event::Eof) => break,
798    ///         _ => (),
799    ///     }
800    /// }
801    /// assert_eq!(count, 3);
802    /// assert_eq!(txt, vec!["Test".to_string(), "Test 2".to_string()]);
803    /// ```
804    ///
805    /// [namespace name]: https://www.w3.org/TR/xml-names11/#dt-NSName
806    /// [`Empty`]: Event::Empty
807    /// [`Start`]: Event::Start
808    /// [`End`]: Event::End
809    pub fn resolve_event<'i>(&self, event: Event<'i>) -> (ResolveResult<'_>, Event<'i>) {
810        use Event::*;
811
812        match event {
813            Empty(e) => (self.resolve_prefix(e.name().prefix(), true), Empty(e)),
814            Start(e) => (self.resolve_prefix(e.name().prefix(), true), Start(e)),
815            End(e) => (self.resolve_prefix(e.name().prefix(), true), End(e)),
816            e => (ResolveResult::Unbound, e),
817        }
818    }
819
820    /// Resolves given optional prefix (usually got from [`QName`]) into a corresponding namespace.
821    ///
822    /// # Parameters
823    /// - `prefix`: prefix to resolve, usually result of [`QName::prefix()`];
824    /// - `use_default`: whether to try to translate `None` prefix to the currently default namespace
825    ///   (bound using `xmlns="default namespace"`) or return [`ResolveResult::Unbound`].
826    ///   For attribute names this should be set to `false` and for element names to `true`.
827    pub fn resolve_prefix(&self, prefix: Option<Prefix>, use_default: bool) -> ResolveResult<'_> {
828        // Find the last defined binding that corresponds to the given prefix
829        let mut iter = self.bindings.iter().rev();
830        match (prefix, use_default) {
831            // Attribute name has no explicit prefix -> Unbound
832            (None, false) => ResolveResult::Unbound,
833            // Element name has no explicit prefix -> find nearest xmlns binding
834            (None, true) => match iter.find(|n| n.prefix_len == 0) {
835                Some(n) => n.namespace(&self.buffer),
836                None => ResolveResult::Unbound,
837            },
838            // Attribute or element name with explicit prefix
839            (Some(p), _) => match iter.find(|n| n.prefix(&self.buffer) == prefix) {
840                Some(n) if n.value_len != 0 => n.namespace(&self.buffer),
841                // Not found or binding reset (corresponds to `xmlns:p=""`)
842                _ => ResolveResult::Unknown(p.into_inner().to_vec()),
843            },
844        }
845    }
846
847    /// Returns all the bindings currently in effect except the default `xml` and `xmlns` bindings.
848    ///
849    /// # Examples
850    ///
851    /// This example shows what results the returned iterator would return after
852    /// reading each event of a simple XML.
853    ///
854    /// ```
855    /// # use pretty_assertions::assert_eq;
856    /// use quick_xml::name::{Namespace, PrefixDeclaration};
857    /// use quick_xml::NsReader;
858    ///
859    /// let src = "<root>
860    ///   <a xmlns=\"a1\" xmlns:a=\"a2\">
861    ///     <b xmlns=\"b1\" xmlns:b=\"b2\">
862    ///       <c/>
863    ///     </b>
864    ///     <d/>
865    ///   </a>
866    /// </root>";
867    /// let mut reader = NsReader::from_str(src);
868    /// reader.config_mut().trim_text(true);
869    /// // No bindings at the beginning
870    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![]);
871    ///
872    /// reader.read_resolved_event()?; // <root>
873    /// // No bindings declared on root
874    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![]);
875    ///
876    /// reader.read_resolved_event()?; // <a>
877    /// // Two bindings declared on "a"
878    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![
879    ///     (PrefixDeclaration::Default, Namespace(b"a1")),
880    ///     (PrefixDeclaration::Named(b"a"), Namespace(b"a2"))
881    /// ]);
882    ///
883    /// reader.read_resolved_event()?; // <b>
884    /// // The default prefix got overridden and new "b" prefix
885    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![
886    ///     (PrefixDeclaration::Named(b"a"), Namespace(b"a2")),
887    ///     (PrefixDeclaration::Default, Namespace(b"b1")),
888    ///     (PrefixDeclaration::Named(b"b"), Namespace(b"b2"))
889    /// ]);
890    ///
891    /// reader.read_resolved_event()?; // <c/>
892    /// // Still the same
893    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![
894    ///     (PrefixDeclaration::Named(b"a"), Namespace(b"a2")),
895    ///     (PrefixDeclaration::Default, Namespace(b"b1")),
896    ///     (PrefixDeclaration::Named(b"b"), Namespace(b"b2"))
897    /// ]);
898    ///
899    /// reader.read_resolved_event()?; // </b>
900    /// // Still the same
901    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![
902    ///     (PrefixDeclaration::Named(b"a"), Namespace(b"a2")),
903    ///     (PrefixDeclaration::Default, Namespace(b"b1")),
904    ///     (PrefixDeclaration::Named(b"b"), Namespace(b"b2"))
905    /// ]);
906    ///
907    /// reader.read_resolved_event()?; // <d/>
908    /// // </b> got closed so back to the bindings declared on <a>
909    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![
910    ///     (PrefixDeclaration::Default, Namespace(b"a1")),
911    ///     (PrefixDeclaration::Named(b"a"), Namespace(b"a2"))
912    /// ]);
913    ///
914    /// reader.read_resolved_event()?; // </a>
915    /// // Still the same
916    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![
917    ///     (PrefixDeclaration::Default, Namespace(b"a1")),
918    ///     (PrefixDeclaration::Named(b"a"), Namespace(b"a2"))
919    /// ]);
920    ///
921    /// reader.read_resolved_event()?; // </root>
922    /// // <a> got closed
923    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![]);
924    /// # quick_xml::Result::Ok(())
925    /// ```
926    #[inline]
927    pub const fn bindings(&self) -> NamespaceBindingsIter<'_> {
928        NamespaceBindingsIter {
929            resolver: self,
930            // We initialize the cursor to 2 to skip the two default namespaces xml: and xmlns:
931            cursor: 2,
932        }
933    }
934
935    /// Returns all the bindings on the specified level, including the default
936    /// `xml` and `xmlns` bindings.
937    ///
938    /// # Parameters
939    /// - `level`: the nesting level of an XML tag. The document without tags has
940    ///   level 0, at which default bindings are declared. The root tag has level 1
941    ///   and all other tags has levels > 1. If specify level more than [current], the
942    ///   empty iterator is returned.
943    ///
944    /// # Examples
945    ///
946    /// This example shows what results the returned iterator would return on each
947    /// level after reaning some events of a simple XML.
948    ///
949    /// ```
950    /// # use pretty_assertions::assert_eq;
951    /// use quick_xml::name::{Namespace, PrefixDeclaration};
952    /// use quick_xml::NsReader;
953    ///
954    /// let src = "<root>
955    ///   <a xmlns=\"a1\" xmlns:a=\"a2\">
956    ///     <b xmlns=\"b1\" xmlns:b=\"b2\">
957    ///       <c/>
958    ///     </b>
959    ///     <d/>
960    ///   </a>
961    /// </root>";
962    /// let mut reader = NsReader::from_str(src);
963    /// reader.config_mut().trim_text(true);
964    /// reader.read_resolved_event()?; // <root>
965    /// reader.read_resolved_event()?; // <a>
966    /// reader.read_resolved_event()?; // <b>
967    /// reader.read_resolved_event()?; // <c/>
968    ///
969    /// // Default bindings at the beginning
970    /// assert_eq!(reader.resolver().bindings_of(0).collect::<Vec<_>>(), vec![
971    ///     (PrefixDeclaration::Named(b"xml"), Namespace(b"http://www.w3.org/XML/1998/namespace")),
972    ///     (PrefixDeclaration::Named(b"xmlns"), Namespace(b"http://www.w3.org/2000/xmlns/")),
973    /// ]);
974    ///
975    /// // No bindings declared on root
976    /// assert_eq!(reader.resolver().bindings_of(1).collect::<Vec<_>>(), vec![]);
977    ///
978    /// // Two bindings declared on "a"
979    /// assert_eq!(reader.resolver().bindings_of(2).collect::<Vec<_>>(), vec![
980    ///     (PrefixDeclaration::Default, Namespace(b"a1")),
981    ///     (PrefixDeclaration::Named(b"a"), Namespace(b"a2")),
982    /// ]);
983    ///
984    /// // Two bindings declared on "b"
985    /// assert_eq!(reader.resolver().bindings_of(3).collect::<Vec<_>>(), vec![
986    ///     (PrefixDeclaration::Default, Namespace(b"b1")),
987    ///     (PrefixDeclaration::Named(b"b"), Namespace(b"b2")),
988    /// ]);
989    ///
990    /// // No bindings declared on "c"
991    /// assert_eq!(reader.resolver().bindings_of(4).collect::<Vec<_>>(), vec![]);
992    ///
993    /// // No bindings on non-existent level
994    /// assert_eq!(reader.resolver().bindings_of(5).collect::<Vec<_>>(), vec![]);
995    /// # quick_xml::Result::Ok(())
996    /// ```
997    ///
998    /// [current]: Self::level
999    pub const fn bindings_of(&self, level: u16) -> NamespaceBindingsOfLevelIter<'_> {
1000        NamespaceBindingsOfLevelIter {
1001            resolver: self,
1002            cursor: 0,
1003            level,
1004        }
1005    }
1006
1007    /// Returns the number of [`push`] calls that were not followed by [`pop`] calls.
1008    ///
1009    /// Due to use of `u16` for level number the number of nested tags in XML
1010    /// are limited by [`u16::MAX`], but that is enough for any real application.
1011    ///
1012    /// # Example
1013    ///
1014    /// ```
1015    /// # use pretty_assertions::assert_eq;
1016    /// # use quick_xml::events::BytesStart;
1017    /// # use quick_xml::name::{Namespace, NamespaceResolver, PrefixDeclaration, QName, ResolveResult};
1018    /// #
1019    /// let mut resolver = NamespaceResolver::default();
1020    ///
1021    /// assert_eq!(resolver.level(), 0);
1022    ///
1023    /// resolver.push(&BytesStart::new("tag"));
1024    /// assert_eq!(resolver.level(), 1);
1025    ///
1026    /// resolver.pop();
1027    /// assert_eq!(resolver.level(), 0);
1028    ///
1029    /// // pop from empty resolver does nothing
1030    /// resolver.pop();
1031    /// assert_eq!(resolver.level(), 0);
1032    /// ```
1033    ///
1034    /// [`push`]: Self::push
1035    /// [`pop`]: Self::pop
1036    pub const fn level(&self) -> u16 {
1037        self.nesting_level
1038    }
1039}
1040
1041////////////////////////////////////////////////////////////////////////////////////////////////////
1042
1043/// Iterator on the current declared namespace bindings. Returns pairs of the _(prefix, namespace)_.
1044///
1045/// See [`NamespaceResolver::bindings`] for documentation.
1046#[derive(Debug, Clone)]
1047pub struct NamespaceBindingsIter<'a> {
1048    resolver: &'a NamespaceResolver,
1049    cursor: usize,
1050}
1051
1052impl<'a> Iterator for NamespaceBindingsIter<'a> {
1053    type Item = (PrefixDeclaration<'a>, Namespace<'a>);
1054
1055    fn next(&mut self) -> Option<(PrefixDeclaration<'a>, Namespace<'a>)> {
1056        while let Some(binding) = self.resolver.bindings.get(self.cursor) {
1057            self.cursor += 1; // We increment for next read
1058
1059            // We check if the key has not been overridden by having a look
1060            // at the namespaces declared after in the array
1061            let prefix = binding.prefix(&self.resolver.buffer);
1062            if self.resolver.bindings[self.cursor..]
1063                .iter()
1064                .any(|ne| prefix == ne.prefix(&self.resolver.buffer))
1065            {
1066                continue; // Overridden
1067            }
1068            if let ResolveResult::Bound(namespace) = binding.namespace(&self.resolver.buffer) {
1069                let prefix = match prefix {
1070                    Some(Prefix(prefix)) => PrefixDeclaration::Named(prefix),
1071                    None => PrefixDeclaration::Default,
1072                };
1073                return Some((prefix, namespace));
1074            }
1075        }
1076        None // We have exhausted the array
1077    }
1078
1079    fn size_hint(&self) -> (usize, Option<usize>) {
1080        // Real count could be less if some namespaces was overridden
1081        (0, Some(self.resolver.bindings.len() - self.cursor))
1082    }
1083}
1084
1085impl<'a> FusedIterator for NamespaceBindingsIter<'a> {}
1086
1087/// The previous name for [`NamespaceBindingsIter`].
1088pub type PrefixIter<'a> = NamespaceBindingsIter<'a>;
1089
1090/// Iterator on the declared namespace bindings on specified level. Returns pairs of the _(prefix, namespace)_.
1091///
1092/// See [`NamespaceResolver::bindings_of`] for documentation.
1093#[derive(Debug, Clone)]
1094pub struct NamespaceBindingsOfLevelIter<'a> {
1095    resolver: &'a NamespaceResolver,
1096    cursor: usize,
1097    level: u16,
1098}
1099
1100impl<'a> Iterator for NamespaceBindingsOfLevelIter<'a> {
1101    type Item = (PrefixDeclaration<'a>, Namespace<'a>);
1102
1103    fn next(&mut self) -> Option<(PrefixDeclaration<'a>, Namespace<'a>)> {
1104        while let Some(binding) = self.resolver.bindings.get(self.cursor) {
1105            self.cursor += 1; // We increment for next read
1106            if binding.level < self.level {
1107                continue;
1108            }
1109            if binding.level > self.level {
1110                break;
1111            }
1112
1113            if let ResolveResult::Bound(namespace) = binding.namespace(&self.resolver.buffer) {
1114                let prefix = match binding.prefix(&self.resolver.buffer) {
1115                    Some(Prefix(prefix)) => PrefixDeclaration::Named(prefix),
1116                    None => PrefixDeclaration::Default,
1117                };
1118                return Some((prefix, namespace));
1119            }
1120        }
1121        None // We have exhausted the array
1122    }
1123
1124    fn size_hint(&self) -> (usize, Option<usize>) {
1125        // Real count could be less
1126        (0, Some(self.resolver.bindings.len() - self.cursor))
1127    }
1128}
1129
1130impl<'a> FusedIterator for NamespaceBindingsOfLevelIter<'a> {}
1131
1132////////////////////////////////////////////////////////////////////////////////////////////////////
1133
1134#[cfg(test)]
1135mod namespaces {
1136    use super::*;
1137    use pretty_assertions::assert_eq;
1138    use ResolveResult::*;
1139
1140    /// Unprefixed attribute names (resolved with `false` flag) never have a namespace
1141    /// according to <https://www.w3.org/TR/xml-names11/#defaulting>:
1142    ///
1143    /// > A default namespace declaration applies to all unprefixed element names
1144    /// > within its scope. Default namespace declarations do not apply directly
1145    /// > to attribute names; the interpretation of unprefixed attributes is
1146    /// > determined by the element on which they appear.
1147    mod unprefixed {
1148        use super::*;
1149        use pretty_assertions::assert_eq;
1150
1151        /// Basic tests that checks that basic resolver functionality is working
1152        #[test]
1153        fn basic() {
1154            let name = QName(b"simple");
1155            let ns = Namespace(b"default");
1156
1157            let mut resolver = NamespaceResolver::default();
1158            let s = resolver.buffer.len();
1159
1160            resolver
1161                .push(&BytesStart::from_content(" xmlns='default'", 0))
1162                .unwrap();
1163            assert_eq!(&resolver.buffer[s..], b"default");
1164
1165            // Check that tags without namespaces does not change result
1166            resolver.push(&BytesStart::from_content("", 0)).unwrap();
1167            assert_eq!(&resolver.buffer[s..], b"default");
1168            resolver.pop();
1169
1170            assert_eq!(&resolver.buffer[s..], b"default");
1171            assert_eq!(
1172                resolver.resolve(name, true),
1173                (Bound(ns), LocalName(b"simple"))
1174            );
1175            assert_eq!(
1176                resolver.resolve(name, false),
1177                (Unbound, LocalName(b"simple"))
1178            );
1179        }
1180
1181        /// Test adding a second level of namespaces, which replaces the previous binding
1182        #[test]
1183        fn override_namespace() {
1184            let name = QName(b"simple");
1185            let old_ns = Namespace(b"old");
1186            let new_ns = Namespace(b"new");
1187
1188            let mut resolver = NamespaceResolver::default();
1189            let s = resolver.buffer.len();
1190
1191            resolver
1192                .push(&BytesStart::from_content(" xmlns='old'", 0))
1193                .unwrap();
1194            resolver
1195                .push(&BytesStart::from_content(" xmlns='new'", 0))
1196                .unwrap();
1197
1198            assert_eq!(&resolver.buffer[s..], b"oldnew");
1199            assert_eq!(
1200                resolver.resolve(name, true),
1201                (Bound(new_ns), LocalName(b"simple"))
1202            );
1203            assert_eq!(
1204                resolver.resolve(name, false),
1205                (Unbound, LocalName(b"simple"))
1206            );
1207
1208            resolver.pop();
1209            assert_eq!(&resolver.buffer[s..], b"old");
1210            assert_eq!(
1211                resolver.resolve(name, true),
1212                (Bound(old_ns), LocalName(b"simple"))
1213            );
1214            assert_eq!(
1215                resolver.resolve(name, false),
1216                (Unbound, LocalName(b"simple"))
1217            );
1218        }
1219
1220        /// Test adding a second level of namespaces, which reset the previous binding
1221        /// to not bound state by specifying an empty namespace name.
1222        ///
1223        /// See <https://www.w3.org/TR/xml-names11/#scoping>
1224        #[test]
1225        fn reset() {
1226            let name = QName(b"simple");
1227            let old_ns = Namespace(b"old");
1228
1229            let mut resolver = NamespaceResolver::default();
1230            let s = resolver.buffer.len();
1231
1232            resolver
1233                .push(&BytesStart::from_content(" xmlns='old'", 0))
1234                .unwrap();
1235            resolver
1236                .push(&BytesStart::from_content(" xmlns=''", 0))
1237                .unwrap();
1238
1239            assert_eq!(&resolver.buffer[s..], b"old");
1240            assert_eq!(
1241                resolver.resolve(name, true),
1242                (Unbound, LocalName(b"simple"))
1243            );
1244            assert_eq!(
1245                resolver.resolve(name, false),
1246                (Unbound, LocalName(b"simple"))
1247            );
1248
1249            resolver.pop();
1250            assert_eq!(&resolver.buffer[s..], b"old");
1251            assert_eq!(
1252                resolver.resolve(name, true),
1253                (Bound(old_ns), LocalName(b"simple"))
1254            );
1255            assert_eq!(
1256                resolver.resolve(name, false),
1257                (Unbound, LocalName(b"simple"))
1258            );
1259        }
1260    }
1261
1262    mod declared_prefix {
1263        use super::*;
1264        use pretty_assertions::assert_eq;
1265
1266        /// Basic tests that checks that basic resolver functionality is working
1267        #[test]
1268        fn basic() {
1269            let name = QName(b"p:with-declared-prefix");
1270            let ns = Namespace(b"default");
1271
1272            let mut resolver = NamespaceResolver::default();
1273            let s = resolver.buffer.len();
1274
1275            resolver
1276                .push(&BytesStart::from_content(" xmlns:p='default'", 0))
1277                .unwrap();
1278            assert_eq!(&resolver.buffer[s..], b"pdefault");
1279
1280            // Check that tags without namespaces does not change result
1281            resolver.push(&BytesStart::from_content("", 0)).unwrap();
1282            assert_eq!(&resolver.buffer[s..], b"pdefault");
1283            resolver.pop();
1284
1285            assert_eq!(&resolver.buffer[s..], b"pdefault");
1286            assert_eq!(
1287                resolver.resolve(name, true),
1288                (Bound(ns), LocalName(b"with-declared-prefix"))
1289            );
1290            assert_eq!(
1291                resolver.resolve(name, false),
1292                (Bound(ns), LocalName(b"with-declared-prefix"))
1293            );
1294        }
1295
1296        /// Test adding a second level of namespaces, which replaces the previous binding
1297        #[test]
1298        fn override_namespace() {
1299            let name = QName(b"p:with-declared-prefix");
1300            let old_ns = Namespace(b"old");
1301            let new_ns = Namespace(b"new");
1302
1303            let mut resolver = NamespaceResolver::default();
1304            let s = resolver.buffer.len();
1305
1306            resolver
1307                .push(&BytesStart::from_content(" xmlns:p='old'", 0))
1308                .unwrap();
1309            resolver
1310                .push(&BytesStart::from_content(" xmlns:p='new'", 0))
1311                .unwrap();
1312
1313            assert_eq!(&resolver.buffer[s..], b"poldpnew");
1314            assert_eq!(
1315                resolver.resolve(name, true),
1316                (Bound(new_ns), LocalName(b"with-declared-prefix"))
1317            );
1318            assert_eq!(
1319                resolver.resolve(name, false),
1320                (Bound(new_ns), LocalName(b"with-declared-prefix"))
1321            );
1322
1323            resolver.pop();
1324            assert_eq!(&resolver.buffer[s..], b"pold");
1325            assert_eq!(
1326                resolver.resolve(name, true),
1327                (Bound(old_ns), LocalName(b"with-declared-prefix"))
1328            );
1329            assert_eq!(
1330                resolver.resolve(name, false),
1331                (Bound(old_ns), LocalName(b"with-declared-prefix"))
1332            );
1333        }
1334
1335        /// Test adding a second level of namespaces, which reset the previous binding
1336        /// to not bound state by specifying an empty namespace name.
1337        ///
1338        /// See <https://www.w3.org/TR/xml-names11/#scoping>
1339        #[test]
1340        fn reset() {
1341            let name = QName(b"p:with-declared-prefix");
1342            let old_ns = Namespace(b"old");
1343
1344            let mut resolver = NamespaceResolver::default();
1345            let s = resolver.buffer.len();
1346
1347            resolver
1348                .push(&BytesStart::from_content(" xmlns:p='old'", 0))
1349                .unwrap();
1350            resolver
1351                .push(&BytesStart::from_content(" xmlns:p=''", 0))
1352                .unwrap();
1353
1354            assert_eq!(&resolver.buffer[s..], b"poldp");
1355            assert_eq!(
1356                resolver.resolve(name, true),
1357                (Unknown(b"p".to_vec()), LocalName(b"with-declared-prefix"))
1358            );
1359            assert_eq!(
1360                resolver.resolve(name, false),
1361                (Unknown(b"p".to_vec()), LocalName(b"with-declared-prefix"))
1362            );
1363
1364            resolver.pop();
1365            assert_eq!(&resolver.buffer[s..], b"pold");
1366            assert_eq!(
1367                resolver.resolve(name, true),
1368                (Bound(old_ns), LocalName(b"with-declared-prefix"))
1369            );
1370            assert_eq!(
1371                resolver.resolve(name, false),
1372                (Bound(old_ns), LocalName(b"with-declared-prefix"))
1373            );
1374        }
1375    }
1376
1377    /// Tests for `xml` and `xmlns` built-in prefixes.
1378    ///
1379    /// See <https://www.w3.org/TR/xml-names11/#xmlReserved>
1380    mod builtin_prefixes {
1381        use super::*;
1382
1383        mod xml {
1384            use super::*;
1385            use pretty_assertions::assert_eq;
1386
1387            /// `xml` prefix are always defined, it is not required to define it explicitly.
1388            #[test]
1389            fn undeclared() {
1390                let name = QName(b"xml:random");
1391                let namespace = RESERVED_NAMESPACE_XML.1;
1392
1393                let resolver = NamespaceResolver::default();
1394
1395                assert_eq!(
1396                    resolver.resolve(name, true),
1397                    (Bound(namespace), LocalName(b"random"))
1398                );
1399
1400                assert_eq!(
1401                    resolver.resolve(name, false),
1402                    (Bound(namespace), LocalName(b"random"))
1403                );
1404            }
1405
1406            /// `xml` prefix can be declared but it must be bound to the value
1407            /// `http://www.w3.org/XML/1998/namespace`
1408            #[test]
1409            fn rebound_to_correct_ns() {
1410                let mut resolver = NamespaceResolver::default();
1411                let s = resolver.buffer.len();
1412                resolver.push(
1413                    &BytesStart::from_content(
1414                        " xmlns:xml='http://www.w3.org/XML/1998/namespace'",
1415                        0,
1416                    ),
1417                ).expect("`xml` prefix should be possible to bound to `http://www.w3.org/XML/1998/namespace`");
1418                assert_eq!(&resolver.buffer[s..], b"");
1419            }
1420
1421            /// `xml` prefix cannot be re-declared to another namespace
1422            #[test]
1423            fn rebound_to_incorrect_ns() {
1424                let mut resolver = NamespaceResolver::default();
1425                let s = resolver.buffer.len();
1426                assert_eq!(
1427                    resolver.push(&BytesStart::from_content(
1428                        " xmlns:xml='not_correct_namespace'",
1429                        0,
1430                    )),
1431                    Err(NamespaceError::InvalidXmlPrefixBind(
1432                        b"not_correct_namespace".to_vec()
1433                    )),
1434                );
1435                assert_eq!(&resolver.buffer[s..], b"");
1436            }
1437
1438            /// `xml` prefix cannot be unbound
1439            #[test]
1440            fn unbound() {
1441                let mut resolver = NamespaceResolver::default();
1442                let s = resolver.buffer.len();
1443                assert_eq!(
1444                    resolver.push(&BytesStart::from_content(" xmlns:xml=''", 0)),
1445                    Err(NamespaceError::InvalidXmlPrefixBind(b"".to_vec())),
1446                );
1447                assert_eq!(&resolver.buffer[s..], b"");
1448            }
1449
1450            /// Other prefix cannot be bound to `xml` namespace
1451            #[test]
1452            fn other_prefix_bound_to_xml_namespace() {
1453                let mut resolver = NamespaceResolver::default();
1454                let s = resolver.buffer.len();
1455                assert_eq!(
1456                    resolver.push(&BytesStart::from_content(
1457                        " xmlns:not_xml='http://www.w3.org/XML/1998/namespace'",
1458                        0,
1459                    )),
1460                    Err(NamespaceError::InvalidPrefixForXml(b"not_xml".to_vec())),
1461                );
1462                assert_eq!(&resolver.buffer[s..], b"");
1463            }
1464        }
1465
1466        mod xmlns {
1467            use super::*;
1468            use pretty_assertions::assert_eq;
1469
1470            /// `xmlns` prefix are always defined, it is forbidden to define it explicitly
1471            #[test]
1472            fn undeclared() {
1473                let name = QName(b"xmlns:random");
1474                let namespace = RESERVED_NAMESPACE_XMLNS.1;
1475
1476                let resolver = NamespaceResolver::default();
1477
1478                assert_eq!(
1479                    resolver.resolve(name, true),
1480                    (Bound(namespace), LocalName(b"random"))
1481                );
1482
1483                assert_eq!(
1484                    resolver.resolve(name, false),
1485                    (Bound(namespace), LocalName(b"random"))
1486                );
1487            }
1488
1489            /// `xmlns` prefix cannot be re-declared event to its own namespace
1490            #[test]
1491            fn rebound_to_correct_ns() {
1492                let mut resolver = NamespaceResolver::default();
1493                let s = resolver.buffer.len();
1494                assert_eq!(
1495                    resolver.push(&BytesStart::from_content(
1496                        " xmlns:xmlns='http://www.w3.org/2000/xmlns/'",
1497                        0,
1498                    )),
1499                    Err(NamespaceError::InvalidXmlnsPrefixBind(
1500                        b"http://www.w3.org/2000/xmlns/".to_vec()
1501                    )),
1502                );
1503                assert_eq!(&resolver.buffer[s..], b"");
1504            }
1505
1506            /// `xmlns` prefix cannot be re-declared
1507            #[test]
1508            fn rebound_to_incorrect_ns() {
1509                let mut resolver = NamespaceResolver::default();
1510                let s = resolver.buffer.len();
1511                assert_eq!(
1512                    resolver.push(&BytesStart::from_content(
1513                        " xmlns:xmlns='not_correct_namespace'",
1514                        0,
1515                    )),
1516                    Err(NamespaceError::InvalidXmlnsPrefixBind(
1517                        b"not_correct_namespace".to_vec()
1518                    )),
1519                );
1520                assert_eq!(&resolver.buffer[s..], b"");
1521            }
1522
1523            /// `xmlns` prefix cannot be unbound
1524            #[test]
1525            fn unbound() {
1526                let mut resolver = NamespaceResolver::default();
1527                let s = resolver.buffer.len();
1528                assert_eq!(
1529                    resolver.push(&BytesStart::from_content(" xmlns:xmlns=''", 0)),
1530                    Err(NamespaceError::InvalidXmlnsPrefixBind(b"".to_vec())),
1531                );
1532                assert_eq!(&resolver.buffer[s..], b"");
1533            }
1534
1535            /// Other prefix cannot be bound to `xmlns` namespace
1536            #[test]
1537            fn other_prefix_bound_to_xmlns_namespace() {
1538                let mut resolver = NamespaceResolver::default();
1539                let s = resolver.buffer.len();
1540                assert_eq!(
1541                    resolver.push(&BytesStart::from_content(
1542                        " xmlns:not_xmlns='http://www.w3.org/2000/xmlns/'",
1543                        0,
1544                    )),
1545                    Err(NamespaceError::InvalidPrefixForXmlns(b"not_xmlns".to_vec())),
1546                );
1547                assert_eq!(&resolver.buffer[s..], b"");
1548            }
1549        }
1550    }
1551
1552    #[test]
1553    fn undeclared_prefix() {
1554        let name = QName(b"unknown:prefix");
1555
1556        let resolver = NamespaceResolver::default();
1557
1558        assert_eq!(
1559            resolver.buffer,
1560            b"xmlhttp://www.w3.org/XML/1998/namespacexmlnshttp://www.w3.org/2000/xmlns/"
1561        );
1562        assert_eq!(
1563            resolver.resolve(name, true),
1564            (Unknown(b"unknown".to_vec()), LocalName(b"prefix"))
1565        );
1566        assert_eq!(
1567            resolver.resolve(name, false),
1568            (Unknown(b"unknown".to_vec()), LocalName(b"prefix"))
1569        );
1570    }
1571
1572    /// Checks how the QName is decomposed to a prefix and a local name
1573    #[test]
1574    fn prefix_and_local_name() {
1575        let name = QName(b"foo:bus");
1576        assert_eq!(name.prefix(), Some(Prefix(b"foo")));
1577        assert_eq!(name.local_name(), LocalName(b"bus"));
1578        assert_eq!(name.decompose(), (LocalName(b"bus"), Some(Prefix(b"foo"))));
1579
1580        let name = QName(b"foo:");
1581        assert_eq!(name.prefix(), Some(Prefix(b"foo")));
1582        assert_eq!(name.local_name(), LocalName(b""));
1583        assert_eq!(name.decompose(), (LocalName(b""), Some(Prefix(b"foo"))));
1584
1585        let name = QName(b":foo");
1586        assert_eq!(name.prefix(), Some(Prefix(b"")));
1587        assert_eq!(name.local_name(), LocalName(b"foo"));
1588        assert_eq!(name.decompose(), (LocalName(b"foo"), Some(Prefix(b""))));
1589
1590        let name = QName(b"foo:bus:baz");
1591        assert_eq!(name.prefix(), Some(Prefix(b"foo")));
1592        assert_eq!(name.local_name(), LocalName(b"bus:baz"));
1593        assert_eq!(
1594            name.decompose(),
1595            (LocalName(b"bus:baz"), Some(Prefix(b"foo")))
1596        );
1597    }
1598}