Skip to main content

deser_xml/
de.rs

1use std::borrow::Cow;
2
3use deser_core::de::{
4    self, ContentKey, Deserialize, DeserializeDriver, LexicalRules, deserialize_value,
5};
6use deser_core::{
7    Atom, ContainerShape, Error, ErrorKind, Event, Order, Source, Text, TrackLocations,
8};
9use quick_xml::XmlVersion;
10use quick_xml::events::{BytesRef, BytesStart, Event as XmlEvent};
11use quick_xml::name::{QName, ResolveResult};
12use quick_xml::reader::NsReader;
13
14use crate::Names;
15use crate::mixed::WhitespaceDepths;
16use crate::root::{Declarations, RootData};
17
18/// Configures how XML documents are deserialized.
19///
20/// See the [crate documentation](crate) for how XML maps onto the data
21/// model of deser.
22#[derive(Debug, Clone, PartialEq, Eq)]
23pub struct DeserializerConfig {
24    pub(crate) names: Names,
25    resolve_namespaces: bool,
26
27    context: deser_core::Context,
28}
29
30impl Default for DeserializerConfig {
31    fn default() -> DeserializerConfig {
32        DeserializerConfig::new()
33    }
34}
35
36impl DeserializerConfig {
37    /// Creates the default configuration.
38    pub const fn new() -> DeserializerConfig {
39        DeserializerConfig {
40            names: Names::new(),
41            resolve_namespaces: false,
42
43            context: deser_core::Context::new(),
44        }
45    }
46
47    /// Returns a builder for the configuration (see [`DeserializerConfigBuilder`]).
48    pub const fn builder() -> DeserializerConfigBuilder {
49        DeserializerConfigBuilder::new()
50    }
51
52    /// Returns a builder that starts with this configuration.
53    pub const fn into_builder(self) -> DeserializerConfigBuilder {
54        DeserializerConfigBuilder { value: self }
55    }
56
57    /// Sets the context the values are deserialized in.
58    ///
59    /// The values of the context are the defaults of the extension values
60    /// of the state (see [`Context`](deser_core::Context)), for instance
61    /// the variants of open enums.  The deserializers and readers created
62    /// with the configuration use this context.  A context set
63    /// on the driver takes precedence.
64    pub fn set_context(&mut self, context: deser_core::Context) {
65        self.context = context;
66    }
67
68    /// Returns the configuration without its context (for the frames of
69    /// streams, which get the context of the stream).
70    pub(crate) fn without_context(&self) -> DeserializerConfig {
71        let mut config = self.clone();
72        config.context = deser_core::Context::default();
73        config
74    }
75
76    /// Returns the context the values are deserialized in.
77    pub fn context(&self) -> &deser_core::Context {
78        &self.context
79    }
80
81    /// Sets the prefix of the keys of attributes.
82    ///
83    /// The default is `@`: `<a href="x"/>` is `{"@href": "x"}`.
84    pub const fn set_attribute_prefix(&mut self, prefix: &'static str) {
85        self.names.attribute_prefix = prefix;
86    }
87
88    /// Sets the key of the text of elements that are maps.
89    ///
90    /// The default is `$text`: `<a href="x">y</a>` is
91    /// `{"@href": "x", "$text": "y"}`.
92    pub const fn set_text_key(&mut self, key: &'static str) {
93        self.names.text_key = key;
94    }
95
96    /// Sets the prefixes of namespaces.
97    ///
98    /// Names are passed on as written in the document (`atom:link`),
99    /// unless their namespace has a prefix here: then they are written
100    /// with this prefix, whichever prefix the document uses.  The empty
101    /// prefix leaves only the local name.  Names in other namespaces are
102    /// passed on as written or, if namespaces are
103    /// [resolved](Self::set_resolve_namespaces), as `{uri}local`.  The table
104    /// can be written with [`prefixes!`](crate::prefixes).
105    ///
106    /// ```
107    /// use deser_xml::DeserializerConfig;
108    ///
109    /// #[derive(deser::Deserialize)]
110    /// struct Feed {
111    ///     title: String,
112    ///     #[deser(rename = "dc:creator")]
113    ///     creator: String,
114    /// }
115    ///
116    /// const CONFIG: DeserializerConfig = DeserializerConfig::new().namespaces(&[
117    ///     ("", "http://www.w3.org/2005/Atom"),
118    ///     ("dc", "http://purl.org/dc/elements/1.1/"),
119    /// ]);
120    /// let feed: Feed = CONFIG.from_str(r#"
121    ///     <a:feed xmlns:a="http://www.w3.org/2005/Atom"
122    ///             xmlns:x="http://purl.org/dc/elements/1.1/">
123    ///       <a:title>Example</a:title>
124    ///       <x:creator>Jane</x:creator>
125    ///     </a:feed>
126    /// "#).unwrap();
127    /// assert_eq!(feed.title, "Example");
128    /// assert_eq!(feed.creator, "Jane");
129    /// ```
130    pub const fn namespaces(
131        mut self,
132        namespaces: &'static [(&'static str, &'static str)],
133    ) -> DeserializerConfig {
134        self.names.namespaces = namespaces;
135        self
136    }
137
138    /// Enables or disables resolving namespaces.
139    ///
140    /// By default names are passed on as written in the document.  If
141    /// namespaces are resolved, names in a namespace are passed on as
142    /// `{uri}local` (the notation of James Clark, attributes are
143    /// `@{uri}local`) unless the namespace has a
144    /// [prefix](Self::namespaces), so the prefixes of the document do not
145    /// matter.  Names without namespace are their local name, the `xml`
146    /// prefix is kept (`@xml:lang`).  Prefixes that are not declared are
147    /// an error.  The default is `false`.
148    ///
149    /// The names can be written with [`qname!`](crate::qname) and
150    /// [`namespace!`](crate::namespace):
151    ///
152    /// ```
153    /// use deser_xml::DeserializerConfig;
154    ///
155    /// deser_xml::namespace!(atom = "http://www.w3.org/2005/Atom");
156    ///
157    /// #[derive(deser::Deserialize)]
158    /// struct Link {
159    ///     #[deser(rename = "@href")]
160    ///     href: String,
161    /// }
162    ///
163    /// #[derive(deser::Deserialize)]
164    /// struct Feed {
165    ///     #[deser(rename = atom!("title"))]
166    ///     title: String,
167    ///     #[deser(rename = atom!("link"))]
168    ///     link: Link,
169    /// }
170    ///
171    /// const CONFIG: DeserializerConfig =
172    ///     DeserializerConfig::builder().resolve_namespaces(true).build();
173    /// let xml = r#"
174    ///     <feed xmlns="http://www.w3.org/2005/Atom">
175    ///       <title>Example</title>
176    ///       <link href="/a"/>
177    ///     </feed>
178    /// "#;
179    /// let feed: Feed = CONFIG.from_str(xml).unwrap();
180    /// assert_eq!(feed.title, "Example");
181    /// assert_eq!(feed.link.href, "/a");
182    /// ```
183    pub const fn set_resolve_namespaces(&mut self, yes: bool) {
184        self.resolve_namespaces = yes;
185    }
186
187    /// Deserializes a value from a string with this configuration.
188    pub fn from_str<'de, T: Deserialize<'de>>(&self, s: &'de str) -> Result<T, Error> {
189        deserialize_value(|driver| self.drive_str(s, driver))
190    }
191
192    /// The part of [`from_str`](Self::from_str) that does not depend on the type
193    /// of the value, it exists once.
194    fn drive_str<'de>(
195        &self,
196        s: &'de str,
197        driver: &mut DeserializeDriver<'_, 'de>,
198    ) -> Result<(), Error> {
199        de::Deserializer::drive(
200            &mut Deserializer::from_str_with_config(s, self.clone()),
201            driver,
202        )
203    }
204
205    /// Deserializes a value from bytes with this configuration.
206    ///
207    /// The input must be UTF-8.
208    pub fn from_slice<'de, T: Deserialize<'de>>(&self, bytes: &'de [u8]) -> Result<T, Error> {
209        deserialize_value(|driver| self.drive_slice(bytes, driver))
210    }
211
212    /// The part of [`from_slice`](Self::from_slice) that does not depend on the type
213    /// of the value, it exists once.
214    fn drive_slice<'de>(
215        &self,
216        bytes: &'de [u8],
217        driver: &mut DeserializeDriver<'_, 'de>,
218    ) -> Result<(), Error> {
219        de::Deserializer::drive(
220            &mut Deserializer::from_slice_with_config(bytes, self.clone()),
221            driver,
222        )
223    }
224}
225
226/// Builds a [`DeserializerConfig`].
227///
228/// The methods have the names of the setters of [`DeserializerConfig`] (without `set_`).
229#[derive(Debug, Clone)]
230#[must_use]
231pub struct DeserializerConfigBuilder {
232    value: DeserializerConfig,
233}
234
235impl DeserializerConfigBuilder {
236    /// Creates a builder that starts with the default.
237    pub const fn new() -> DeserializerConfigBuilder {
238        DeserializerConfigBuilder {
239            value: DeserializerConfig::new(),
240        }
241    }
242
243    /// Sets the prefix of the keys of attributes.
244    ///
245    /// See [`DeserializerConfig::set_attribute_prefix`].
246    pub const fn attribute_prefix(mut self, prefix: &'static str) -> DeserializerConfigBuilder {
247        self.value.set_attribute_prefix(prefix);
248        self
249    }
250
251    /// Sets the key of the text of elements that are maps.
252    ///
253    /// See [`DeserializerConfig::set_text_key`].
254    pub const fn text_key(mut self, key: &'static str) -> DeserializerConfigBuilder {
255        self.value.set_text_key(key);
256        self
257    }
258
259    /// Enables or disables resolving namespaces.
260    ///
261    /// See [`DeserializerConfig::set_resolve_namespaces`].
262    pub const fn resolve_namespaces(mut self, yes: bool) -> DeserializerConfigBuilder {
263        self.value.set_resolve_namespaces(yes);
264        self
265    }
266
267    /// Sets the context the values are deserialized in.
268    ///
269    /// See [`DeserializerConfig::set_context`].
270    pub fn context(mut self, context: deser_core::Context) -> DeserializerConfigBuilder {
271        self.value.set_context(context);
272        self
273    }
274
275    /// Returns the built [`DeserializerConfig`].
276    pub const fn build(self) -> DeserializerConfig {
277        // the value cannot be moved out of the builder in a const fn as the
278        // builder needs dropping (the context has a destructor)
279        // SAFETY: the value is read once and the builder is forgotten
280        let value = unsafe { core::ptr::read(&self.value) };
281        core::mem::forget(self);
282        value
283    }
284}
285
286impl Default for DeserializerConfigBuilder {
287    fn default() -> DeserializerConfigBuilder {
288        DeserializerConfigBuilder::new()
289    }
290}
291
292/// Deserializes a value from an XML string.
293///
294/// ```
295/// #[derive(deser::Deserialize)]
296/// struct Link {
297///     #[deser(rename = "@href")]
298///     href: String,
299/// }
300///
301/// let link: Link = deser_xml::from_str(r#"<a href="/x"/>"#).unwrap();
302/// assert_eq!(link.href, "/x");
303/// ```
304pub fn from_str<'de, T: Deserialize<'de>>(s: &'de str) -> Result<T, Error> {
305    DeserializerConfig::new().from_str(s)
306}
307
308/// Deserializes a value from UTF-8 encoded XML.
309pub fn from_slice<'de, T: Deserialize<'de>>(bytes: &'de [u8]) -> Result<T, Error> {
310    DeserializerConfig::new().from_slice(bytes)
311}
312
313/// Deserializes XML documents.
314pub struct Deserializer<'a> {
315    input: &'a str,
316    error: Option<Error>,
317    config: DeserializerConfig,
318}
319
320impl<'a> Deserializer<'a> {
321    /// Creates a deserializer for a string.
322    #[allow(clippy::should_implement_trait)]
323    pub fn from_str(input: &'a str) -> Deserializer<'a> {
324        Deserializer::from_str_with_config(input, DeserializerConfig::new())
325    }
326
327    /// Creates a deserializer for a string with the given configuration.
328    pub fn from_str_with_config(input: &'a str, config: DeserializerConfig) -> Deserializer<'a> {
329        Deserializer {
330            input,
331            error: None,
332            config,
333        }
334    }
335
336    /// Creates a deserializer for UTF-8 encoded bytes.
337    pub fn from_slice(input: &'a [u8]) -> Deserializer<'a> {
338        Deserializer::from_slice_with_config(input, DeserializerConfig::new())
339    }
340
341    /// Creates a deserializer for UTF-8 encoded bytes with the given
342    /// configuration.
343    pub fn from_slice_with_config(input: &'a [u8], config: DeserializerConfig) -> Deserializer<'a> {
344        // a byte order mark is not part of the document
345        let input = input.strip_prefix(b"\xef\xbb\xbf").unwrap_or(input);
346        match std::str::from_utf8(input) {
347            Ok(input) => Deserializer::from_str_with_config(input, config),
348            Err(err) => Deserializer {
349                input: "",
350                error: Some(Error::with_offset(
351                    ErrorKind::Syntax,
352                    "input is not valid UTF-8",
353                    err.valid_up_to(),
354                )),
355                config,
356            },
357        }
358    }
359
360    /// Returns the configuration.
361    pub fn config(&self) -> &DeserializerConfig {
362        &self.config
363    }
364
365    /// Deserializes the document.
366    pub fn deserialize<T: Deserialize<'a>>(&mut self) -> Result<T, Error> {
367        de::Deserializer::deserialize(self)
368    }
369
370    /// Deserializes the document with a configured driver.
371    ///
372    /// The callback is invoked with the driver before the value is
373    /// deserialized, for instance to add [`Layer`](deser_core::de::Layer)s.
374    pub fn deserialize_with<T, F>(&mut self, setup: F) -> Result<T, Error>
375    where
376        T: Deserialize<'a>,
377        F: FnOnce(&mut DeserializeDriver<'_, 'a>),
378    {
379        de::Deserializer::deserialize_with(self, setup)
380    }
381
382    /// Parses the document and feeds the events into the driver.
383    ///
384    /// Events are emitted while the document is parsed.  Text is passed on
385    /// borrowed from the input unless it has references or line breaks
386    /// that are normalized.
387    ///
388    /// The context of the configuration is given to the driver (values that
389    /// the context of the driver has take precedence, see
390    /// [`DeserializeDriver::set_default_context`]).
391    pub fn drive(&mut self, driver: &mut DeserializeDriver<'_, 'a>) -> Result<(), Error> {
392        if !self.config.context.is_empty() {
393            driver.set_default_context(self.config.context.clone());
394        }
395        if let Some(err) = self.error.take() {
396            return Err(err);
397        }
398        let state = driver.state_mut();
399        if TrackLocations::of(state) {
400            Source(self.input.into()).set(state);
401        }
402        TEXT_RULES.set_default(state);
403        // elements with attributes are text for types that expect text,
404        // text is an element for types that expect maps
405        ContentKey(self.config.names.text_key).set(state);
406        *state.get_mut::<Names>() = self.config.names.clone();
407        Parser {
408            input: self.input,
409            config: &self.config,
410            reader: NsReader::from_str(self.input),
411            stack: Vec::new(),
412            root_done: false,
413            root: None,
414            declarations: None,
415        }
416        .run(driver)
417        .map_err(|mut err| {
418            err.resolve_position(self.input.as_bytes());
419            err
420        })
421    }
422}
423
424impl<'a> de::Deserializer<'a> for Deserializer<'a> {
425    fn drive(&mut self, driver: &mut DeserializeDriver<'_, 'a>) -> Result<(), Error> {
426        Deserializer::drive(self, driver)
427    }
428}
429
430/// How the text of XML is interpreted.
431///
432/// Booleans are `true` and `false` (XML Schema also allows `1` and `0`,
433/// which are integers here), an empty element is a missing value for types
434/// that do not accept it (`<age/>` is `None` for an `Option<u32>`).
435const TEXT_RULES: LexicalRules = {
436    let mut rules = LexicalRules::STRICT;
437    rules.set_empty_is_null(true);
438    rules
439};
440
441/// A byte range in the input.
442type Range = (usize, usize);
443
444/// The text of an element that was not passed on yet.
445enum PendingText<'a> {
446    None,
447    Borrowed(&'a str, Range),
448    Owned(String, Range),
449}
450
451impl<'a> PendingText<'a> {
452    fn push(&mut self, text: Cow<'a, str>, range: Range) {
453        *self = match (std::mem::replace(self, PendingText::None), text) {
454            (PendingText::None, Cow::Borrowed(text)) => PendingText::Borrowed(text, range),
455            (PendingText::None, Cow::Owned(text)) => PendingText::Owned(text, range),
456            (PendingText::Borrowed(prev, (start, _)), text) => {
457                PendingText::Owned(prev.to_string() + &text, (start, range.1))
458            }
459            (PendingText::Owned(mut prev, (start, _)), text) => {
460                prev.push_str(&text);
461                PendingText::Owned(prev, (start, range.1))
462            }
463        };
464    }
465
466    fn is_blank(&self) -> bool {
467        match self {
468            PendingText::None => true,
469            PendingText::Borrowed(text, _) => is_blank(text),
470            PendingText::Owned(text, _) => is_blank(text),
471        }
472    }
473
474    /// Emits the text as lexical atom.
475    fn emit(self, driver: &mut DeserializeDriver<'_, 'a>, fallback: Range) -> Result<(), Error> {
476        match self {
477            PendingText::None => emit_at(driver, Atom::Lexical(Text::borrowed("")), fallback),
478            PendingText::Borrowed(text, range) => {
479                driver.state_mut().set_input_range(range.0, range.1);
480                driver.emit_borrowed(Atom::Lexical(Text::borrowed(text)))
481            }
482            PendingText::Owned(text, range) => {
483                emit_at(driver, Atom::Lexical(Text::owned(text)), range)
484            }
485        }
486    }
487}
488
489fn is_blank(text: &str) -> bool {
490    text.bytes()
491        .all(|b| matches!(b, b' ' | b'\t' | b'\n' | b'\r'))
492}
493
494/// An open element.
495struct Element<'a> {
496    /// `true` once the element was passed on as map.
497    is_map: bool,
498    text: PendingText<'a>,
499    /// The range of the start tag.
500    start: Range,
501}
502
503struct Parser<'a, 'c> {
504    input: &'a str,
505    config: &'c DeserializerConfig,
506    reader: NsReader<&'a [u8]>,
507    stack: Vec<Element<'a>>,
508    root_done: bool,
509    /// The name and the namespaces of the root element until they are
510    /// attached to its first event.
511    root: Option<RootData>,
512    /// The namespaces declared on the last element that was started until
513    /// they are attached to its first event.
514    declarations: Option<Vec<(String, String)>>,
515}
516
517impl<'a> Parser<'a, '_> {
518    fn run(mut self, driver: &mut DeserializeDriver<'_, 'a>) -> Result<(), Error> {
519        loop {
520            let start = self.position();
521            let event = self
522                .reader
523                .read_event()
524                .map_err(|err| xml_error(err, self.reader.error_position() as usize))?;
525            let range = (start, self.position());
526            match event {
527                XmlEvent::Start(ref tag) => self.start(driver, tag, range)?,
528                XmlEvent::Empty(ref tag) => {
529                    self.start(driver, tag, range)?;
530                    self.end(driver, range)?;
531                }
532                XmlEvent::End(_) => self.end(driver, range)?,
533                XmlEvent::Text(text) => {
534                    self.text(text.xml_content(XmlVersion::Implicit1_0), range)?
535                }
536                XmlEvent::CData(text) => {
537                    self.text(text.xml_content(XmlVersion::Implicit1_0), range)?
538                }
539                XmlEvent::GeneralRef(reference) => {
540                    let text = resolve_reference(&reference, start)?;
541                    self.text(Cow::Owned(text.to_string()), range)?
542                }
543                XmlEvent::Decl(_)
544                | XmlEvent::PI(_)
545                | XmlEvent::Comment(_)
546                | XmlEvent::DocType(_) => {}
547                XmlEvent::Eof => {
548                    if !self.stack.is_empty() {
549                        return Err(Error::with_offset(
550                            ErrorKind::EndOfFile,
551                            "unexpected end of input, an element is not closed",
552                            start,
553                        ));
554                    }
555                    if !self.root_done {
556                        return Err(Error::with_offset(
557                            ErrorKind::EndOfFile,
558                            "no root element",
559                            start,
560                        ));
561                    }
562                    return Ok(());
563                }
564            }
565        }
566    }
567
568    fn position(&self) -> usize {
569        self.reader.buffer_position() as usize
570    }
571
572    /// Passes on the element on top of the stack as map if it's not yet.
573    fn make_map(&mut self, driver: &mut DeserializeDriver<'_, 'a>) -> Result<(), Error> {
574        if !self.stack.last().unwrap().is_map {
575            self.attach_element(driver);
576            let element = self.stack.last_mut().unwrap();
577            element.is_map = true;
578            emit_at(
579                driver,
580                Event::MapStart({
581                    let mut shape = ContainerShape::with_order(Order::Significant);
582                    shape.set_multimap(true);
583                    shape
584                }),
585                element.start,
586            )?;
587        }
588        self.flush_text(driver)
589    }
590
591    /// Passes on the text of the element on top of the stack as entry.
592    fn flush_text(&mut self, driver: &mut DeserializeDriver<'_, 'a>) -> Result<(), Error> {
593        let element = self.stack.last_mut().unwrap();
594        // whitespace between elements is not text, unless the content is
595        // mixed
596        if matches!(element.text, PendingText::None)
597            || (element.text.is_blank() && !WhitespaceDepths::applies(driver.state()))
598        {
599            element.text = PendingText::None;
600            return Ok(());
601        }
602        let text = std::mem::replace(&mut element.text, PendingText::None);
603        let range = match text {
604            PendingText::Borrowed(_, range) | PendingText::Owned(_, range) => range,
605            PendingText::None => unreachable!(),
606        };
607        emit_at(
608            driver,
609            Atom::Lexical(Text::borrowed(self.config.names.text_key)),
610            range,
611        )?;
612        text.emit(driver, range)
613    }
614
615    fn start(
616        &mut self,
617        driver: &mut DeserializeDriver<'_, 'a>,
618        tag: &BytesStart<'a>,
619        range: Range,
620    ) -> Result<(), Error> {
621        if self.stack.is_empty() {
622            if self.root_done {
623                return Err(Error::with_offset(
624                    ErrorKind::Syntax,
625                    "more than one root element",
626                    range.0,
627                ));
628            }
629            self.root = Some(self.root_data(tag, range.0)?);
630        } else {
631            self.make_map(driver)?;
632            let name = self.name(tag.name(), false, range.0)?;
633            emit_key(driver, name, range)?;
634            // most elements declare nothing, the attributes are only
635            // looked at if they might
636            if tag.attributes_raw().contains("xmlns") {
637                let declarations = self.declarations(tag, false, range.0)?;
638                if !declarations.is_empty() {
639                    self.declarations = Some(declarations);
640                }
641            }
642        }
643        self.stack.push(Element {
644            is_map: false,
645            text: PendingText::None,
646            start: range,
647        });
648
649        for attr in tag.attributes() {
650            let attr = attr.map_err(|err| {
651                Error::with_offset(
652                    ErrorKind::Syntax,
653                    format!("invalid attribute: {err}"),
654                    range.0,
655                )
656            })?;
657            let raw = attr.key.as_ref();
658            // namespace declarations are not data
659            if raw == "xmlns" || raw.starts_with("xmlns:") {
660                continue;
661            }
662            self.make_map(driver)?;
663            let name = self.name(attr.key, true, range.0)?;
664            emit_key(driver, name, range)?;
665            let value = attr
666                .normalized_value(XmlVersion::Implicit1_0)
667                .map_err(|err| xml_error(err, range.0))?;
668            match reborrow(self.input, &value) {
669                Some(value) => {
670                    driver.state_mut().set_input_range(range.0, range.1);
671                    driver.emit_borrowed(Atom::Lexical(Text::borrowed(value)))?;
672                }
673                None => emit_at(driver, Atom::Lexical(Text::borrowed(&value)), range)?,
674            }
675        }
676        Ok(())
677    }
678
679    /// Returns the name of the root element and the namespaces declared
680    /// on it.
681    ///
682    /// Namespaces with a configured prefix are declared with it as that's
683    /// how names in them are passed on.
684    fn root_data(&self, tag: &BytesStart<'a>, offset: usize) -> Result<RootData, Error> {
685        Ok(RootData {
686            name: Some(self.name(tag.name(), false, offset)?.into_owned()),
687            namespaces: self.declarations(tag, true, offset)?,
688        })
689    }
690
691    /// Returns the namespaces declared on an element.
692    ///
693    /// Namespaces with a configured prefix are declared with it as that's
694    /// how names in them are passed on.  Undeclaring the default namespace
695    /// (`xmlns=""`) is a declaration with an empty URI, except on the root
696    /// where there is nothing to undeclare.
697    fn declarations(
698        &self,
699        tag: &BytesStart<'a>,
700        is_root: bool,
701        offset: usize,
702    ) -> Result<Vec<(String, String)>, Error> {
703        let mut namespaces: Vec<(String, String)> = Vec::new();
704        // invalid attributes are reported when the attributes are passed on
705        for attr in tag.attributes().flatten() {
706            let raw: &str = attr.key.as_ref();
707            let prefix = match raw.strip_prefix("xmlns") {
708                Some("") => "",
709                Some(rest) => match rest.strip_prefix(':') {
710                    Some(prefix) => prefix,
711                    None => continue,
712                },
713                None => continue,
714            };
715            let uri = attr
716                .normalized_value(XmlVersion::Implicit1_0)
717                .map_err(|err| xml_error(err, offset))?;
718            if uri.is_empty() && (is_root || !prefix.is_empty()) {
719                continue;
720            }
721            let prefix = match self.config.names.namespaces.iter().find(|(_, x)| *x == uri) {
722                Some((alias, _)) => alias,
723                None => prefix,
724            };
725            if !namespaces.iter().any(|(x, _)| x == prefix) {
726                namespaces.push((prefix.to_string(), uri.into_owned()));
727            }
728        }
729        Ok(namespaces)
730    }
731
732    /// Attaches the name and the namespaces of the root element or the
733    /// namespaces declared on another element to its first event.
734    ///
735    /// The first event of an element comes before the events of the
736    /// elements in it, so the element they are for is the last one that was
737    /// started.
738    fn attach_element(&mut self, driver: &mut DeserializeDriver<'_, 'a>) {
739        if let Some(root) = self.root.take() {
740            *driver.state_mut().event_mut::<RootData>() = root;
741        }
742        if let Some(declarations) = self.declarations.take() {
743            driver.state_mut().event_mut::<Declarations>().0 = declarations;
744        }
745    }
746
747    fn end(&mut self, driver: &mut DeserializeDriver<'_, 'a>, range: Range) -> Result<(), Error> {
748        if self.stack.last().unwrap().is_map {
749            self.flush_text(driver)?;
750            self.stack.pop();
751            emit_at(driver, Event::MapEnd, range)?;
752            WhitespaceDepths::prune(driver.state_mut());
753        } else {
754            self.attach_element(driver);
755            let element = self.stack.pop().unwrap();
756            element.text.emit(driver, element.start)?;
757        }
758        if self.stack.is_empty() {
759            self.root_done = true;
760        }
761        Ok(())
762    }
763
764    fn text(&mut self, text: Cow<'a, str>, range: Range) -> Result<(), Error> {
765        match self.stack.last_mut() {
766            Some(element) => {
767                element.text.push(text, range);
768                Ok(())
769            }
770            None if is_blank(&text) => Ok(()),
771            None => Err(Error::with_offset(
772                ErrorKind::Syntax,
773                "text outside of the root element",
774                range.0,
775            )),
776        }
777    }
778
779    /// Returns the key of an element or attribute.
780    fn name(
781        &self,
782        name: QName<'_>,
783        is_attribute: bool,
784        offset: usize,
785    ) -> Result<Cow<'a, str>, Error> {
786        let names = &self.config.names;
787        let written: &str = name.as_ref();
788        let local_name = name.local_name();
789        let local: &str = local_name.as_ref();
790        let mut key = match self.namespace(name, is_attribute) {
791            Namespace::Alias("") => Cow::Owned(local.to_string()),
792            Namespace::Alias(alias) => Cow::Owned(format!("{alias}:{local}")),
793            Namespace::Uri(uri) => Cow::Owned(format!("{{{uri}}}{local}")),
794            Namespace::Unknown if self.config.resolve_namespaces => {
795                return Err(Error::with_offset(
796                    ErrorKind::Syntax,
797                    format!("the prefix of `{written}` is not declared"),
798                    offset,
799                ));
800            }
801            Namespace::Written | Namespace::Unknown => match reborrow(self.input, written) {
802                Some(written) => Cow::Borrowed(written),
803                None => Cow::Owned(written.to_string()),
804            },
805        };
806        if is_attribute && !names.attribute_prefix.is_empty() {
807            key = Cow::Owned(format!("{}{}", names.attribute_prefix, key));
808        }
809        Ok(key)
810    }
811
812    /// Returns how the namespace of a name is written.
813    fn namespace(&self, name: QName<'_>, is_attribute: bool) -> Namespace {
814        let namespaces = self.config.names.namespaces;
815        let resolve = self.config.resolve_namespaces;
816        if namespaces.is_empty() && !resolve {
817            return Namespace::Written;
818        }
819        let resolver = self.reader.resolver();
820        let (ns, _) = if is_attribute {
821            resolver.resolve_attribute(name)
822        } else {
823            resolver.resolve_element(name)
824        };
825        match ns {
826            ResolveResult::Bound(ns) => {
827                let uri: &str = ns.as_ref();
828                if let Some((alias, _)) = namespaces.iter().find(|(_, x)| *x == uri) {
829                    Namespace::Alias(alias)
830                } else if !resolve {
831                    Namespace::Written
832                } else if uri == XML_NAMESPACE {
833                    Namespace::Alias("xml")
834                } else {
835                    Namespace::Uri(uri.to_string())
836                }
837            }
838            ResolveResult::Unbound => Namespace::Written,
839            ResolveResult::Unknown(_) => Namespace::Unknown,
840        }
841    }
842}
843
844/// The namespace of the `xml` prefix.
845pub(crate) const XML_NAMESPACE: &str = "http://www.w3.org/XML/1998/namespace";
846
847/// How the namespace of a name is written.
848enum Namespace {
849    /// The name is passed on as written.
850    Written,
851    /// The name has the configured prefix.
852    Alias(&'static str),
853    /// The name is `{uri}local`.
854    Uri(String),
855    /// The prefix is not declared.
856    Unknown,
857}
858
859/// Returns the text as a slice of the input if it is one.
860fn reborrow<'a>(input: &'a str, text: &str) -> Option<&'a str> {
861    let start = (text.as_ptr() as usize).checked_sub(input.as_ptr() as usize)?;
862    let end = start.checked_add(text.len())?;
863    input
864        .get(start..end)
865        .filter(|x| x.as_ptr() == text.as_ptr())
866}
867
868/// Resolves a character or entity reference.
869///
870/// Only the predefined entities are supported, the entities of document
871/// types are never expanded.
872fn resolve_reference(reference: &BytesRef<'_>, offset: usize) -> Result<char, Error> {
873    if let Some(c) = reference
874        .resolve_char_ref()
875        .map_err(|err| xml_error(err, offset))?
876    {
877        return Ok(c);
878    }
879    match &*reference.xml_content(XmlVersion::Implicit1_0) {
880        "lt" => Ok('<'),
881        "gt" => Ok('>'),
882        "amp" => Ok('&'),
883        "apos" => Ok('\''),
884        "quot" => Ok('"'),
885        name => Err(Error::with_offset(
886            ErrorKind::Syntax,
887            format!("unknown entity `&{name};`"),
888            offset,
889        )),
890    }
891}
892
893fn xml_error(err: quick_xml::Error, offset: usize) -> Error {
894    Error::with_offset(ErrorKind::Syntax, format!("invalid XML: {err}"), offset)
895}
896
897fn emit_key<'a>(
898    driver: &mut DeserializeDriver<'_, 'a>,
899    key: Cow<'a, str>,
900    range: Range,
901) -> Result<(), Error> {
902    driver.state_mut().set_input_range(range.0, range.1);
903    match key {
904        Cow::Borrowed(key) => driver.emit_borrowed(Atom::Lexical(Text::borrowed(key))),
905        Cow::Owned(key) => driver.emit(Atom::Lexical(Text::owned(key))),
906    }
907}
908
909fn emit_at<'e, E: Into<Event<'e>>>(
910    driver: &mut DeserializeDriver<'_, '_>,
911    event: E,
912    range: Range,
913) -> Result<(), Error> {
914    driver.state_mut().set_input_range(range.0, range.1);
915    driver.emit(event)
916}