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                if let Some(prefix) = k.as_namespace_binding() {
666                    self.add(prefix, Namespace(&v))?;
667                }
668            } else {
669                break;
670            }
671        }
672        Ok(())
673    }
674
675    /// Ends a top-most scope by popping all [namespace bindings], that was added by
676    /// last call to [`Self::push()`] and [`Self::add()`].
677    ///
678    /// [namespace bindings]: https://www.w3.org/TR/xml-names11/#dt-NSDecl
679    pub fn pop(&mut self) {
680        self.nesting_level = self.nesting_level.saturating_sub(1);
681        let current_level = self.nesting_level;
682        // from the back (most deeply nested scope), look for the first scope that is still valid
683        match self.bindings.iter().rposition(|n| n.level <= current_level) {
684            // none of the namespaces are valid, remove all of them
685            None => {
686                self.buffer.clear();
687                self.bindings.clear();
688            }
689            // drop all namespaces past the last valid namespace
690            Some(last_valid_pos) => {
691                if let Some(len) = self.bindings.get(last_valid_pos + 1).map(|n| n.start) {
692                    self.buffer.truncate(len);
693                    self.bindings.truncate(last_valid_pos + 1);
694                }
695            }
696        }
697    }
698
699    /// Resolves a potentially qualified **element name** or **attribute name**
700    /// into _(namespace name, local name)_.
701    ///
702    /// _Qualified_ names have the form `local-name` or `prefix:local-name` where the `prefix`
703    /// is defined on any containing XML element via `xmlns:prefix="the:namespace:uri"`.
704    /// The namespace prefix can be defined on the same element as the name in question.
705    ///
706    /// The method returns following results depending on the `name` shape, `attribute` flag
707    /// and the presence of the default namespace on element or any of its parents:
708    ///
709    /// |use_default|`xmlns="..."`|QName              |ResolveResult          |LocalName
710    /// |-----------|-------------|-------------------|-----------------------|------------
711    /// |`false`    |_(any)_      |`local-name`       |[`Unbound`]            |`local-name`
712    /// |`false`    |_(any)_      |`prefix:local-name`|[`Bound`] / [`Unknown`]|`local-name`
713    /// |`true`     |Not defined  |`local-name`       |[`Unbound`]            |`local-name`
714    /// |`true`     |Defined      |`local-name`       |[`Bound`] (to `xmlns`) |`local-name`
715    /// |`true`     |_(any)_      |`prefix:local-name`|[`Bound`] / [`Unknown`]|`local-name`
716    ///
717    /// # Parameters
718    /// - `name`: probably qualified name to resolve;
719    /// - `use_default`: whether to try to translate `None` prefix to the currently default namespace
720    ///   (bound using `xmlns="default namespace"`) or return [`ResolveResult::Unbound`].
721    ///   For attribute names this should be set to `false` and for element names to `true`.
722    ///
723    /// # Lifetimes
724    ///
725    /// - `'n`: lifetime of a name. Returned local name will be bound to the same
726    ///   lifetime as the name in question.
727    /// - returned namespace name will be bound to the resolver itself
728    ///
729    /// [`Bound`]: ResolveResult::Bound
730    /// [`Unbound`]: ResolveResult::Unbound
731    /// [`Unknown`]: ResolveResult::Unknown
732    #[inline]
733    pub fn resolve<'n>(
734        &self,
735        name: QName<'n>,
736        use_default: bool,
737    ) -> (ResolveResult<'_>, LocalName<'n>) {
738        let (local_name, prefix) = name.decompose();
739        (self.resolve_prefix(prefix, use_default), local_name)
740    }
741
742    /// Convenient method to call `resolve(name, true)`. May be used to clearly
743    /// express that we want to resolve an element name, and not an attribute name.
744    #[inline]
745    pub fn resolve_element<'n>(&self, name: QName<'n>) -> (ResolveResult<'_>, LocalName<'n>) {
746        self.resolve(name, true)
747    }
748
749    /// Convenient method to call `resolve(name, false)`. May be used to clearly
750    /// express that we want to resolve an attribute name, and not an element name.
751    #[inline]
752    pub fn resolve_attribute<'n>(&self, name: QName<'n>) -> (ResolveResult<'_>, LocalName<'n>) {
753        self.resolve(name, false)
754    }
755
756    /// Finds a [namespace name] for a given event, if applicable.
757    ///
758    /// Namespace is resolved only for [`Start`], [`Empty`] and [`End`] events.
759    /// For all other events the concept of namespace is not defined, so
760    /// a [`ResolveResult::Unbound`] is returned.
761    ///
762    /// # Examples
763    ///
764    /// ```
765    /// # use pretty_assertions::assert_eq;
766    /// use quick_xml::events::Event;
767    /// use quick_xml::name::{Namespace, QName, ResolveResult::*};
768    /// use quick_xml::reader::NsReader;
769    ///
770    /// let mut reader = NsReader::from_str(r#"
771    ///     <x:tag1 xmlns:x="www.xxxx" xmlns:y="www.yyyy" att1 = "test">
772    ///        <y:tag2><!--Test comment-->Test</y:tag2>
773    ///        <y:tag2>Test 2</y:tag2>
774    ///     </x:tag1>
775    /// "#);
776    /// reader.config_mut().trim_text(true);
777    ///
778    /// let mut count = 0;
779    /// let mut txt = Vec::new();
780    /// loop {
781    ///     let event = reader.read_event().unwrap();
782    ///     match reader.resolver().resolve_event(event) {
783    ///         (Bound(Namespace(b"www.xxxx")), Event::Start(e)) => {
784    ///             count += 1;
785    ///             assert_eq!(e.local_name(), QName(b"tag1").into());
786    ///         }
787    ///         (Bound(Namespace(b"www.yyyy")), Event::Start(e)) => {
788    ///             count += 1;
789    ///             assert_eq!(e.local_name(), QName(b"tag2").into());
790    ///         }
791    ///         (_, Event::Start(_)) => unreachable!(),
792    ///
793    ///         (_, Event::Text(e)) => {
794    ///             txt.push(e.decode().unwrap().into_owned())
795    ///         }
796    ///         (_, Event::Eof) => break,
797    ///         _ => (),
798    ///     }
799    /// }
800    /// assert_eq!(count, 3);
801    /// assert_eq!(txt, vec!["Test".to_string(), "Test 2".to_string()]);
802    /// ```
803    ///
804    /// [namespace name]: https://www.w3.org/TR/xml-names11/#dt-NSName
805    /// [`Empty`]: Event::Empty
806    /// [`Start`]: Event::Start
807    /// [`End`]: Event::End
808    pub fn resolve_event<'i>(&self, event: Event<'i>) -> (ResolveResult<'_>, Event<'i>) {
809        use Event::*;
810
811        match event {
812            Empty(e) => (self.resolve_prefix(e.name().prefix(), true), Empty(e)),
813            Start(e) => (self.resolve_prefix(e.name().prefix(), true), Start(e)),
814            End(e) => (self.resolve_prefix(e.name().prefix(), true), End(e)),
815            e => (ResolveResult::Unbound, e),
816        }
817    }
818
819    /// Resolves given optional prefix (usually got from [`QName`]) into a corresponding namespace.
820    ///
821    /// # Parameters
822    /// - `prefix`: prefix to resolve, usually result of [`QName::prefix()`];
823    /// - `use_default`: whether to try to translate `None` prefix to the currently default namespace
824    ///   (bound using `xmlns="default namespace"`) or return [`ResolveResult::Unbound`].
825    ///   For attribute names this should be set to `false` and for element names to `true`.
826    pub fn resolve_prefix(&self, prefix: Option<Prefix>, use_default: bool) -> ResolveResult<'_> {
827        // Find the last defined binding that corresponds to the given prefix
828        let mut iter = self.bindings.iter().rev();
829        match (prefix, use_default) {
830            // Attribute name has no explicit prefix -> Unbound
831            (None, false) => ResolveResult::Unbound,
832            // Element name has no explicit prefix -> find nearest xmlns binding
833            (None, true) => match iter.find(|n| n.prefix_len == 0) {
834                Some(n) => n.namespace(&self.buffer),
835                None => ResolveResult::Unbound,
836            },
837            // Attribute or element name with explicit prefix
838            (Some(p), _) => match iter.find(|n| n.prefix(&self.buffer) == prefix) {
839                Some(n) if n.value_len != 0 => n.namespace(&self.buffer),
840                // Not found or binding reset (corresponds to `xmlns:p=""`)
841                _ => ResolveResult::Unknown(p.into_inner().to_vec()),
842            },
843        }
844    }
845
846    /// Returns all the bindings currently in effect except the default `xml` and `xmlns` bindings.
847    ///
848    /// # Examples
849    ///
850    /// This example shows what results the returned iterator would return after
851    /// reading each event of a simple XML.
852    ///
853    /// ```
854    /// # use pretty_assertions::assert_eq;
855    /// use quick_xml::name::{Namespace, PrefixDeclaration};
856    /// use quick_xml::NsReader;
857    ///
858    /// let src = "<root>
859    ///   <a xmlns=\"a1\" xmlns:a=\"a2\">
860    ///     <b xmlns=\"b1\" xmlns:b=\"b2\">
861    ///       <c/>
862    ///     </b>
863    ///     <d/>
864    ///   </a>
865    /// </root>";
866    /// let mut reader = NsReader::from_str(src);
867    /// reader.config_mut().trim_text(true);
868    /// // No bindings at the beginning
869    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![]);
870    ///
871    /// reader.read_resolved_event()?; // <root>
872    /// // No bindings declared on root
873    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![]);
874    ///
875    /// reader.read_resolved_event()?; // <a>
876    /// // Two bindings declared on "a"
877    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![
878    ///     (PrefixDeclaration::Default, Namespace(b"a1")),
879    ///     (PrefixDeclaration::Named(b"a"), Namespace(b"a2"))
880    /// ]);
881    ///
882    /// reader.read_resolved_event()?; // <b>
883    /// // The default prefix got overridden and new "b" prefix
884    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![
885    ///     (PrefixDeclaration::Named(b"a"), Namespace(b"a2")),
886    ///     (PrefixDeclaration::Default, Namespace(b"b1")),
887    ///     (PrefixDeclaration::Named(b"b"), Namespace(b"b2"))
888    /// ]);
889    ///
890    /// reader.read_resolved_event()?; // <c/>
891    /// // Still the same
892    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![
893    ///     (PrefixDeclaration::Named(b"a"), Namespace(b"a2")),
894    ///     (PrefixDeclaration::Default, Namespace(b"b1")),
895    ///     (PrefixDeclaration::Named(b"b"), Namespace(b"b2"))
896    /// ]);
897    ///
898    /// reader.read_resolved_event()?; // </b>
899    /// // Still the same
900    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![
901    ///     (PrefixDeclaration::Named(b"a"), Namespace(b"a2")),
902    ///     (PrefixDeclaration::Default, Namespace(b"b1")),
903    ///     (PrefixDeclaration::Named(b"b"), Namespace(b"b2"))
904    /// ]);
905    ///
906    /// reader.read_resolved_event()?; // <d/>
907    /// // </b> got closed so back to the bindings declared on <a>
908    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![
909    ///     (PrefixDeclaration::Default, Namespace(b"a1")),
910    ///     (PrefixDeclaration::Named(b"a"), Namespace(b"a2"))
911    /// ]);
912    ///
913    /// reader.read_resolved_event()?; // </a>
914    /// // Still the same
915    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![
916    ///     (PrefixDeclaration::Default, Namespace(b"a1")),
917    ///     (PrefixDeclaration::Named(b"a"), Namespace(b"a2"))
918    /// ]);
919    ///
920    /// reader.read_resolved_event()?; // </root>
921    /// // <a> got closed
922    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![]);
923    /// # quick_xml::Result::Ok(())
924    /// ```
925    #[inline]
926    pub const fn bindings(&self) -> NamespaceBindingsIter<'_> {
927        NamespaceBindingsIter {
928            resolver: self,
929            // We initialize the cursor to 2 to skip the two default namespaces xml: and xmlns:
930            cursor: 2,
931        }
932    }
933
934    /// Returns all the bindings on the specified level, including the default
935    /// `xml` and `xmlns` bindings.
936    ///
937    /// # Parameters
938    /// - `level`: the nesting level of an XML tag. The document without tags has
939    ///   level 0, at which default bindings are declared. The root tag has level 1
940    ///   and all other tags has levels > 1. If specify level more than [current], the
941    ///   empty iterator is returned.
942    ///
943    /// # Examples
944    ///
945    /// This example shows what results the returned iterator would return on each
946    /// level after reaning some events of a simple XML.
947    ///
948    /// ```
949    /// # use pretty_assertions::assert_eq;
950    /// use quick_xml::name::{Namespace, PrefixDeclaration};
951    /// use quick_xml::NsReader;
952    ///
953    /// let src = "<root>
954    ///   <a xmlns=\"a1\" xmlns:a=\"a2\">
955    ///     <b xmlns=\"b1\" xmlns:b=\"b2\">
956    ///       <c/>
957    ///     </b>
958    ///     <d/>
959    ///   </a>
960    /// </root>";
961    /// let mut reader = NsReader::from_str(src);
962    /// reader.config_mut().trim_text(true);
963    /// reader.read_resolved_event()?; // <root>
964    /// reader.read_resolved_event()?; // <a>
965    /// reader.read_resolved_event()?; // <b>
966    /// reader.read_resolved_event()?; // <c/>
967    ///
968    /// // Default bindings at the beginning
969    /// assert_eq!(reader.resolver().bindings_of(0).collect::<Vec<_>>(), vec![
970    ///     (PrefixDeclaration::Named(b"xml"), Namespace(b"http://www.w3.org/XML/1998/namespace")),
971    ///     (PrefixDeclaration::Named(b"xmlns"), Namespace(b"http://www.w3.org/2000/xmlns/")),
972    /// ]);
973    ///
974    /// // No bindings declared on root
975    /// assert_eq!(reader.resolver().bindings_of(1).collect::<Vec<_>>(), vec![]);
976    ///
977    /// // Two bindings declared on "a"
978    /// assert_eq!(reader.resolver().bindings_of(2).collect::<Vec<_>>(), vec![
979    ///     (PrefixDeclaration::Default, Namespace(b"a1")),
980    ///     (PrefixDeclaration::Named(b"a"), Namespace(b"a2")),
981    /// ]);
982    ///
983    /// // Two bindings declared on "b"
984    /// assert_eq!(reader.resolver().bindings_of(3).collect::<Vec<_>>(), vec![
985    ///     (PrefixDeclaration::Default, Namespace(b"b1")),
986    ///     (PrefixDeclaration::Named(b"b"), Namespace(b"b2")),
987    /// ]);
988    ///
989    /// // No bindings declared on "c"
990    /// assert_eq!(reader.resolver().bindings_of(4).collect::<Vec<_>>(), vec![]);
991    ///
992    /// // No bindings on non-existent level
993    /// assert_eq!(reader.resolver().bindings_of(5).collect::<Vec<_>>(), vec![]);
994    /// # quick_xml::Result::Ok(())
995    /// ```
996    ///
997    /// [current]: Self::level
998    pub const fn bindings_of(&self, level: u16) -> NamespaceBindingsOfLevelIter<'_> {
999        NamespaceBindingsOfLevelIter {
1000            resolver: self,
1001            cursor: 0,
1002            level,
1003        }
1004    }
1005
1006    /// Returns the number of [`push`] calls that were not followed by [`pop`] calls.
1007    ///
1008    /// Due to use of `u16` for level number the number of nested tags in XML
1009    /// are limited by [`u16::MAX`], but that is enough for any real application.
1010    ///
1011    /// # Example
1012    ///
1013    /// ```
1014    /// # use pretty_assertions::assert_eq;
1015    /// # use quick_xml::events::BytesStart;
1016    /// # use quick_xml::name::{Namespace, NamespaceResolver, PrefixDeclaration, QName, ResolveResult};
1017    /// #
1018    /// let mut resolver = NamespaceResolver::default();
1019    ///
1020    /// assert_eq!(resolver.level(), 0);
1021    ///
1022    /// resolver.push(&BytesStart::new("tag"));
1023    /// assert_eq!(resolver.level(), 1);
1024    ///
1025    /// resolver.pop();
1026    /// assert_eq!(resolver.level(), 0);
1027    ///
1028    /// // pop from empty resolver does nothing
1029    /// resolver.pop();
1030    /// assert_eq!(resolver.level(), 0);
1031    /// ```
1032    ///
1033    /// [`push`]: Self::push
1034    /// [`pop`]: Self::pop
1035    pub const fn level(&self) -> u16 {
1036        self.nesting_level
1037    }
1038}
1039
1040////////////////////////////////////////////////////////////////////////////////////////////////////
1041
1042/// Iterator on the current declared namespace bindings. Returns pairs of the _(prefix, namespace)_.
1043///
1044/// See [`NamespaceResolver::bindings`] for documentation.
1045#[derive(Debug, Clone)]
1046pub struct NamespaceBindingsIter<'a> {
1047    resolver: &'a NamespaceResolver,
1048    cursor: usize,
1049}
1050
1051impl<'a> Iterator for NamespaceBindingsIter<'a> {
1052    type Item = (PrefixDeclaration<'a>, Namespace<'a>);
1053
1054    fn next(&mut self) -> Option<(PrefixDeclaration<'a>, Namespace<'a>)> {
1055        while let Some(binding) = self.resolver.bindings.get(self.cursor) {
1056            self.cursor += 1; // We increment for next read
1057
1058            // We check if the key has not been overridden by having a look
1059            // at the namespaces declared after in the array
1060            let prefix = binding.prefix(&self.resolver.buffer);
1061            if self.resolver.bindings[self.cursor..]
1062                .iter()
1063                .any(|ne| prefix == ne.prefix(&self.resolver.buffer))
1064            {
1065                continue; // Overridden
1066            }
1067            if let ResolveResult::Bound(namespace) = binding.namespace(&self.resolver.buffer) {
1068                let prefix = match prefix {
1069                    Some(Prefix(prefix)) => PrefixDeclaration::Named(prefix),
1070                    None => PrefixDeclaration::Default,
1071                };
1072                return Some((prefix, namespace));
1073            }
1074        }
1075        None // We have exhausted the array
1076    }
1077
1078    fn size_hint(&self) -> (usize, Option<usize>) {
1079        // Real count could be less if some namespaces was overridden
1080        (0, Some(self.resolver.bindings.len() - self.cursor))
1081    }
1082}
1083
1084impl<'a> FusedIterator for NamespaceBindingsIter<'a> {}
1085
1086/// The previous name for [`NamespaceBindingsIter`].
1087pub type PrefixIter<'a> = NamespaceBindingsIter<'a>;
1088
1089/// Iterator on the declared namespace bindings on specified level. Returns pairs of the _(prefix, namespace)_.
1090///
1091/// See [`NamespaceResolver::bindings_of`] for documentation.
1092#[derive(Debug, Clone)]
1093pub struct NamespaceBindingsOfLevelIter<'a> {
1094    resolver: &'a NamespaceResolver,
1095    cursor: usize,
1096    level: u16,
1097}
1098
1099impl<'a> Iterator for NamespaceBindingsOfLevelIter<'a> {
1100    type Item = (PrefixDeclaration<'a>, Namespace<'a>);
1101
1102    fn next(&mut self) -> Option<(PrefixDeclaration<'a>, Namespace<'a>)> {
1103        while let Some(binding) = self.resolver.bindings.get(self.cursor) {
1104            self.cursor += 1; // We increment for next read
1105            if binding.level < self.level {
1106                continue;
1107            }
1108            if binding.level > self.level {
1109                break;
1110            }
1111
1112            if let ResolveResult::Bound(namespace) = binding.namespace(&self.resolver.buffer) {
1113                let prefix = match binding.prefix(&self.resolver.buffer) {
1114                    Some(Prefix(prefix)) => PrefixDeclaration::Named(prefix),
1115                    None => PrefixDeclaration::Default,
1116                };
1117                return Some((prefix, namespace));
1118            }
1119        }
1120        None // We have exhausted the array
1121    }
1122
1123    fn size_hint(&self) -> (usize, Option<usize>) {
1124        // Real count could be less
1125        (0, Some(self.resolver.bindings.len() - self.cursor))
1126    }
1127}
1128
1129impl<'a> FusedIterator for NamespaceBindingsOfLevelIter<'a> {}
1130
1131////////////////////////////////////////////////////////////////////////////////////////////////////
1132
1133#[cfg(test)]
1134mod namespaces {
1135    use super::*;
1136    use pretty_assertions::assert_eq;
1137    use ResolveResult::*;
1138
1139    /// Unprefixed attribute names (resolved with `false` flag) never have a namespace
1140    /// according to <https://www.w3.org/TR/xml-names11/#defaulting>:
1141    ///
1142    /// > A default namespace declaration applies to all unprefixed element names
1143    /// > within its scope. Default namespace declarations do not apply directly
1144    /// > to attribute names; the interpretation of unprefixed attributes is
1145    /// > determined by the element on which they appear.
1146    mod unprefixed {
1147        use super::*;
1148        use pretty_assertions::assert_eq;
1149
1150        /// Basic tests that checks that basic resolver functionality is working
1151        #[test]
1152        fn basic() {
1153            let name = QName(b"simple");
1154            let ns = Namespace(b"default");
1155
1156            let mut resolver = NamespaceResolver::default();
1157            let s = resolver.buffer.len();
1158
1159            resolver
1160                .push(&BytesStart::from_content(" xmlns='default'", 0))
1161                .unwrap();
1162            assert_eq!(&resolver.buffer[s..], b"default");
1163
1164            // Check that tags without namespaces does not change result
1165            resolver.push(&BytesStart::from_content("", 0)).unwrap();
1166            assert_eq!(&resolver.buffer[s..], b"default");
1167            resolver.pop();
1168
1169            assert_eq!(&resolver.buffer[s..], b"default");
1170            assert_eq!(
1171                resolver.resolve(name, true),
1172                (Bound(ns), LocalName(b"simple"))
1173            );
1174            assert_eq!(
1175                resolver.resolve(name, false),
1176                (Unbound, LocalName(b"simple"))
1177            );
1178        }
1179
1180        /// Test adding a second level of namespaces, which replaces the previous binding
1181        #[test]
1182        fn override_namespace() {
1183            let name = QName(b"simple");
1184            let old_ns = Namespace(b"old");
1185            let new_ns = Namespace(b"new");
1186
1187            let mut resolver = NamespaceResolver::default();
1188            let s = resolver.buffer.len();
1189
1190            resolver
1191                .push(&BytesStart::from_content(" xmlns='old'", 0))
1192                .unwrap();
1193            resolver
1194                .push(&BytesStart::from_content(" xmlns='new'", 0))
1195                .unwrap();
1196
1197            assert_eq!(&resolver.buffer[s..], b"oldnew");
1198            assert_eq!(
1199                resolver.resolve(name, true),
1200                (Bound(new_ns), LocalName(b"simple"))
1201            );
1202            assert_eq!(
1203                resolver.resolve(name, false),
1204                (Unbound, LocalName(b"simple"))
1205            );
1206
1207            resolver.pop();
1208            assert_eq!(&resolver.buffer[s..], b"old");
1209            assert_eq!(
1210                resolver.resolve(name, true),
1211                (Bound(old_ns), LocalName(b"simple"))
1212            );
1213            assert_eq!(
1214                resolver.resolve(name, false),
1215                (Unbound, LocalName(b"simple"))
1216            );
1217        }
1218
1219        /// Test adding a second level of namespaces, which reset the previous binding
1220        /// to not bound state by specifying an empty namespace name.
1221        ///
1222        /// See <https://www.w3.org/TR/xml-names11/#scoping>
1223        #[test]
1224        fn reset() {
1225            let name = QName(b"simple");
1226            let old_ns = Namespace(b"old");
1227
1228            let mut resolver = NamespaceResolver::default();
1229            let s = resolver.buffer.len();
1230
1231            resolver
1232                .push(&BytesStart::from_content(" xmlns='old'", 0))
1233                .unwrap();
1234            resolver
1235                .push(&BytesStart::from_content(" xmlns=''", 0))
1236                .unwrap();
1237
1238            assert_eq!(&resolver.buffer[s..], b"old");
1239            assert_eq!(
1240                resolver.resolve(name, true),
1241                (Unbound, LocalName(b"simple"))
1242            );
1243            assert_eq!(
1244                resolver.resolve(name, false),
1245                (Unbound, LocalName(b"simple"))
1246            );
1247
1248            resolver.pop();
1249            assert_eq!(&resolver.buffer[s..], b"old");
1250            assert_eq!(
1251                resolver.resolve(name, true),
1252                (Bound(old_ns), LocalName(b"simple"))
1253            );
1254            assert_eq!(
1255                resolver.resolve(name, false),
1256                (Unbound, LocalName(b"simple"))
1257            );
1258        }
1259    }
1260
1261    mod declared_prefix {
1262        use super::*;
1263        use pretty_assertions::assert_eq;
1264
1265        /// Basic tests that checks that basic resolver functionality is working
1266        #[test]
1267        fn basic() {
1268            let name = QName(b"p:with-declared-prefix");
1269            let ns = Namespace(b"default");
1270
1271            let mut resolver = NamespaceResolver::default();
1272            let s = resolver.buffer.len();
1273
1274            resolver
1275                .push(&BytesStart::from_content(" xmlns:p='default'", 0))
1276                .unwrap();
1277            assert_eq!(&resolver.buffer[s..], b"pdefault");
1278
1279            // Check that tags without namespaces does not change result
1280            resolver.push(&BytesStart::from_content("", 0)).unwrap();
1281            assert_eq!(&resolver.buffer[s..], b"pdefault");
1282            resolver.pop();
1283
1284            assert_eq!(&resolver.buffer[s..], b"pdefault");
1285            assert_eq!(
1286                resolver.resolve(name, true),
1287                (Bound(ns), LocalName(b"with-declared-prefix"))
1288            );
1289            assert_eq!(
1290                resolver.resolve(name, false),
1291                (Bound(ns), LocalName(b"with-declared-prefix"))
1292            );
1293        }
1294
1295        /// Test adding a second level of namespaces, which replaces the previous binding
1296        #[test]
1297        fn override_namespace() {
1298            let name = QName(b"p:with-declared-prefix");
1299            let old_ns = Namespace(b"old");
1300            let new_ns = Namespace(b"new");
1301
1302            let mut resolver = NamespaceResolver::default();
1303            let s = resolver.buffer.len();
1304
1305            resolver
1306                .push(&BytesStart::from_content(" xmlns:p='old'", 0))
1307                .unwrap();
1308            resolver
1309                .push(&BytesStart::from_content(" xmlns:p='new'", 0))
1310                .unwrap();
1311
1312            assert_eq!(&resolver.buffer[s..], b"poldpnew");
1313            assert_eq!(
1314                resolver.resolve(name, true),
1315                (Bound(new_ns), LocalName(b"with-declared-prefix"))
1316            );
1317            assert_eq!(
1318                resolver.resolve(name, false),
1319                (Bound(new_ns), LocalName(b"with-declared-prefix"))
1320            );
1321
1322            resolver.pop();
1323            assert_eq!(&resolver.buffer[s..], b"pold");
1324            assert_eq!(
1325                resolver.resolve(name, true),
1326                (Bound(old_ns), LocalName(b"with-declared-prefix"))
1327            );
1328            assert_eq!(
1329                resolver.resolve(name, false),
1330                (Bound(old_ns), LocalName(b"with-declared-prefix"))
1331            );
1332        }
1333
1334        /// Test adding a second level of namespaces, which reset the previous binding
1335        /// to not bound state by specifying an empty namespace name.
1336        ///
1337        /// See <https://www.w3.org/TR/xml-names11/#scoping>
1338        #[test]
1339        fn reset() {
1340            let name = QName(b"p:with-declared-prefix");
1341            let old_ns = Namespace(b"old");
1342
1343            let mut resolver = NamespaceResolver::default();
1344            let s = resolver.buffer.len();
1345
1346            resolver
1347                .push(&BytesStart::from_content(" xmlns:p='old'", 0))
1348                .unwrap();
1349            resolver
1350                .push(&BytesStart::from_content(" xmlns:p=''", 0))
1351                .unwrap();
1352
1353            assert_eq!(&resolver.buffer[s..], b"poldp");
1354            assert_eq!(
1355                resolver.resolve(name, true),
1356                (Unknown(b"p".to_vec()), LocalName(b"with-declared-prefix"))
1357            );
1358            assert_eq!(
1359                resolver.resolve(name, false),
1360                (Unknown(b"p".to_vec()), LocalName(b"with-declared-prefix"))
1361            );
1362
1363            resolver.pop();
1364            assert_eq!(&resolver.buffer[s..], b"pold");
1365            assert_eq!(
1366                resolver.resolve(name, true),
1367                (Bound(old_ns), LocalName(b"with-declared-prefix"))
1368            );
1369            assert_eq!(
1370                resolver.resolve(name, false),
1371                (Bound(old_ns), LocalName(b"with-declared-prefix"))
1372            );
1373        }
1374    }
1375
1376    /// Tests for `xml` and `xmlns` built-in prefixes.
1377    ///
1378    /// See <https://www.w3.org/TR/xml-names11/#xmlReserved>
1379    mod builtin_prefixes {
1380        use super::*;
1381
1382        mod xml {
1383            use super::*;
1384            use pretty_assertions::assert_eq;
1385
1386            /// `xml` prefix are always defined, it is not required to define it explicitly.
1387            #[test]
1388            fn undeclared() {
1389                let name = QName(b"xml:random");
1390                let namespace = RESERVED_NAMESPACE_XML.1;
1391
1392                let resolver = NamespaceResolver::default();
1393
1394                assert_eq!(
1395                    resolver.resolve(name, true),
1396                    (Bound(namespace), LocalName(b"random"))
1397                );
1398
1399                assert_eq!(
1400                    resolver.resolve(name, false),
1401                    (Bound(namespace), LocalName(b"random"))
1402                );
1403            }
1404
1405            /// `xml` prefix can be declared but it must be bound to the value
1406            /// `http://www.w3.org/XML/1998/namespace`
1407            #[test]
1408            fn rebound_to_correct_ns() {
1409                let mut resolver = NamespaceResolver::default();
1410                let s = resolver.buffer.len();
1411                resolver.push(
1412                    &BytesStart::from_content(
1413                        " xmlns:xml='http://www.w3.org/XML/1998/namespace'",
1414                        0,
1415                    ),
1416                ).expect("`xml` prefix should be possible to bound to `http://www.w3.org/XML/1998/namespace`");
1417                assert_eq!(&resolver.buffer[s..], b"");
1418            }
1419
1420            /// `xml` prefix cannot be re-declared to another namespace
1421            #[test]
1422            fn rebound_to_incorrect_ns() {
1423                let mut resolver = NamespaceResolver::default();
1424                let s = resolver.buffer.len();
1425                assert_eq!(
1426                    resolver.push(&BytesStart::from_content(
1427                        " xmlns:xml='not_correct_namespace'",
1428                        0,
1429                    )),
1430                    Err(NamespaceError::InvalidXmlPrefixBind(
1431                        b"not_correct_namespace".to_vec()
1432                    )),
1433                );
1434                assert_eq!(&resolver.buffer[s..], b"");
1435            }
1436
1437            /// `xml` prefix cannot be unbound
1438            #[test]
1439            fn unbound() {
1440                let mut resolver = NamespaceResolver::default();
1441                let s = resolver.buffer.len();
1442                assert_eq!(
1443                    resolver.push(&BytesStart::from_content(" xmlns:xml=''", 0)),
1444                    Err(NamespaceError::InvalidXmlPrefixBind(b"".to_vec())),
1445                );
1446                assert_eq!(&resolver.buffer[s..], b"");
1447            }
1448
1449            /// Other prefix cannot be bound to `xml` namespace
1450            #[test]
1451            fn other_prefix_bound_to_xml_namespace() {
1452                let mut resolver = NamespaceResolver::default();
1453                let s = resolver.buffer.len();
1454                assert_eq!(
1455                    resolver.push(&BytesStart::from_content(
1456                        " xmlns:not_xml='http://www.w3.org/XML/1998/namespace'",
1457                        0,
1458                    )),
1459                    Err(NamespaceError::InvalidPrefixForXml(b"not_xml".to_vec())),
1460                );
1461                assert_eq!(&resolver.buffer[s..], b"");
1462            }
1463        }
1464
1465        mod xmlns {
1466            use super::*;
1467            use pretty_assertions::assert_eq;
1468
1469            /// `xmlns` prefix are always defined, it is forbidden to define it explicitly
1470            #[test]
1471            fn undeclared() {
1472                let name = QName(b"xmlns:random");
1473                let namespace = RESERVED_NAMESPACE_XMLNS.1;
1474
1475                let resolver = NamespaceResolver::default();
1476
1477                assert_eq!(
1478                    resolver.resolve(name, true),
1479                    (Bound(namespace), LocalName(b"random"))
1480                );
1481
1482                assert_eq!(
1483                    resolver.resolve(name, false),
1484                    (Bound(namespace), LocalName(b"random"))
1485                );
1486            }
1487
1488            /// `xmlns` prefix cannot be re-declared event to its own namespace
1489            #[test]
1490            fn rebound_to_correct_ns() {
1491                let mut resolver = NamespaceResolver::default();
1492                let s = resolver.buffer.len();
1493                assert_eq!(
1494                    resolver.push(&BytesStart::from_content(
1495                        " xmlns:xmlns='http://www.w3.org/2000/xmlns/'",
1496                        0,
1497                    )),
1498                    Err(NamespaceError::InvalidXmlnsPrefixBind(
1499                        b"http://www.w3.org/2000/xmlns/".to_vec()
1500                    )),
1501                );
1502                assert_eq!(&resolver.buffer[s..], b"");
1503            }
1504
1505            /// `xmlns` prefix cannot be re-declared
1506            #[test]
1507            fn rebound_to_incorrect_ns() {
1508                let mut resolver = NamespaceResolver::default();
1509                let s = resolver.buffer.len();
1510                assert_eq!(
1511                    resolver.push(&BytesStart::from_content(
1512                        " xmlns:xmlns='not_correct_namespace'",
1513                        0,
1514                    )),
1515                    Err(NamespaceError::InvalidXmlnsPrefixBind(
1516                        b"not_correct_namespace".to_vec()
1517                    )),
1518                );
1519                assert_eq!(&resolver.buffer[s..], b"");
1520            }
1521
1522            /// `xmlns` prefix cannot be unbound
1523            #[test]
1524            fn unbound() {
1525                let mut resolver = NamespaceResolver::default();
1526                let s = resolver.buffer.len();
1527                assert_eq!(
1528                    resolver.push(&BytesStart::from_content(" xmlns:xmlns=''", 0)),
1529                    Err(NamespaceError::InvalidXmlnsPrefixBind(b"".to_vec())),
1530                );
1531                assert_eq!(&resolver.buffer[s..], b"");
1532            }
1533
1534            /// Other prefix cannot be bound to `xmlns` namespace
1535            #[test]
1536            fn other_prefix_bound_to_xmlns_namespace() {
1537                let mut resolver = NamespaceResolver::default();
1538                let s = resolver.buffer.len();
1539                assert_eq!(
1540                    resolver.push(&BytesStart::from_content(
1541                        " xmlns:not_xmlns='http://www.w3.org/2000/xmlns/'",
1542                        0,
1543                    )),
1544                    Err(NamespaceError::InvalidPrefixForXmlns(b"not_xmlns".to_vec())),
1545                );
1546                assert_eq!(&resolver.buffer[s..], b"");
1547            }
1548        }
1549    }
1550
1551    #[test]
1552    fn undeclared_prefix() {
1553        let name = QName(b"unknown:prefix");
1554
1555        let resolver = NamespaceResolver::default();
1556
1557        assert_eq!(
1558            resolver.buffer,
1559            b"xmlhttp://www.w3.org/XML/1998/namespacexmlnshttp://www.w3.org/2000/xmlns/"
1560        );
1561        assert_eq!(
1562            resolver.resolve(name, true),
1563            (Unknown(b"unknown".to_vec()), LocalName(b"prefix"))
1564        );
1565        assert_eq!(
1566            resolver.resolve(name, false),
1567            (Unknown(b"unknown".to_vec()), LocalName(b"prefix"))
1568        );
1569    }
1570
1571    /// Checks how the QName is decomposed to a prefix and a local name
1572    #[test]
1573    fn prefix_and_local_name() {
1574        let name = QName(b"foo:bus");
1575        assert_eq!(name.prefix(), Some(Prefix(b"foo")));
1576        assert_eq!(name.local_name(), LocalName(b"bus"));
1577        assert_eq!(name.decompose(), (LocalName(b"bus"), Some(Prefix(b"foo"))));
1578
1579        let name = QName(b"foo:");
1580        assert_eq!(name.prefix(), Some(Prefix(b"foo")));
1581        assert_eq!(name.local_name(), LocalName(b""));
1582        assert_eq!(name.decompose(), (LocalName(b""), Some(Prefix(b"foo"))));
1583
1584        let name = QName(b":foo");
1585        assert_eq!(name.prefix(), Some(Prefix(b"")));
1586        assert_eq!(name.local_name(), LocalName(b"foo"));
1587        assert_eq!(name.decompose(), (LocalName(b"foo"), Some(Prefix(b""))));
1588
1589        let name = QName(b"foo:bus:baz");
1590        assert_eq!(name.prefix(), Some(Prefix(b"foo")));
1591        assert_eq!(name.local_name(), LocalName(b"bus:baz"));
1592        assert_eq!(
1593            name.decompose(),
1594            (LocalName(b"bus:baz"), Some(Prefix(b"foo")))
1595        );
1596    }
1597}