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