Skip to main content

oxixml_xml/de/
deserializer.rs

1//! The [`Deserializer`] itself and the free `from_str` / `from_reader` functions.
2
3use std::borrow::Cow;
4#[cfg(feature = "overlapped-lists")]
5use std::collections::VecDeque;
6use std::io::BufRead;
7#[cfg(feature = "overlapped-lists")]
8use std::num::NonZeroUsize;
9
10use serde::de::{
11    self, Deserialize, DeserializeOwned, DeserializeSeed, IntoDeserializer, SeqAccess, Visitor,
12};
13
14use crate::XmlVersion;
15use crate::de::event::{DeEvent, XmlReader};
16use crate::de::map::ElementMapAccess;
17use crate::de::resolver::{EntityResolver, PredefinedEntityResolver};
18use crate::de::simple_type::SimpleTypeDeserializer;
19use crate::de::var;
20use crate::de::xml_read::{IoReader, SliceReader, XmlRead};
21use crate::errors::Error;
22use crate::errors::serialize::DeError;
23use crate::name::QName;
24use crate::reader::NsReader;
25
26////////////////////////////////////////////////////////////////////////////////////////////////////
27
28/// Deserialize an instance of type `T` from a string of XML text.
29pub fn from_str<'de, T>(s: &'de str) -> Result<T, DeError>
30where
31    T: Deserialize<'de>,
32{
33    let mut de = Deserializer::from_str(s);
34    T::deserialize(&mut de)
35}
36
37/// Deserialize from a reader. This method will do internal copies of data
38/// read from `reader`. If you want have a `&str` input and want to borrow
39/// as much as possible, use [`from_str`].
40pub fn from_reader<R, T>(reader: R) -> Result<T, DeError>
41where
42    R: BufRead,
43    T: DeserializeOwned,
44{
45    let mut de = Deserializer::from_reader(reader);
46    T::deserialize(&mut de)
47}
48
49////////////////////////////////////////////////////////////////////////////////////////////////////
50
51/// A structure that deserializes XML into Rust values.
52pub struct Deserializer<'de, R, E: EntityResolver = PredefinedEntityResolver>
53where
54    R: XmlRead<'de>,
55{
56    /// An XML reader that streams events into this deserializer
57    pub(crate) reader: XmlReader<'de, R, E>,
58
59    /// When deserializing sequences sometimes we have to skip unwanted events.
60    /// That events should be stored and then replayed. This is a replay buffer,
61    /// that streams events while not empty. When it exhausted, events will
62    /// requested from [`Self::reader`].
63    #[cfg(feature = "overlapped-lists")]
64    pub(crate) read: VecDeque<DeEvent<'de>>,
65    /// When deserializing sequences sometimes we have to skip events, because XML
66    /// is tolerant to elements order and even if in the XSD order is strictly
67    /// specified (using `xs:sequence`) most of XML parsers allows order violations.
68    /// That means, that elements, forming a sequence, could be overlapped with
69    /// other elements, do not related to that sequence.
70    ///
71    /// In order to support this, deserializer will scan events and skip unwanted
72    /// events, store them here. After call [`Self::start_replay()`] all events
73    /// moved from this to [`Self::read`].
74    #[cfg(feature = "overlapped-lists")]
75    pub(crate) write: VecDeque<DeEvent<'de>>,
76    /// Maximum number of events that can be skipped when processing sequences
77    /// that occur out-of-order. This field is used to prevent potential
78    /// denial-of-service (DoS) attacks which could cause infinite memory
79    /// consumption when parsing a very large amount of XML into a sequence field.
80    #[cfg(feature = "overlapped-lists")]
81    pub(crate) limit: Option<NonZeroUsize>,
82
83    #[cfg(not(feature = "overlapped-lists"))]
84    pub(crate) peek: Option<DeEvent<'de>>,
85
86    /// One-event lookahead past [`Self::peek`]. Filled only by [`Self::peek_second()`]
87    /// and drained by [`Self::next()`], which shifts it into [`Self::peek`]. It stays
88    /// `None` on every code path that does not consult a second event, so ordinary
89    /// deserialization behaves exactly as if this slot did not exist.
90    #[cfg(not(feature = "overlapped-lists"))]
91    pub(crate) peek2: Option<DeEvent<'de>>,
92
93    /// Buffer to store attribute name as a field name exposed to serde consumers
94    pub(crate) key_buf: String,
95}
96
97impl<'de, R, E> Deserializer<'de, R, E>
98where
99    R: XmlRead<'de>,
100    E: EntityResolver,
101{
102    /// Create an XML deserializer from one of the possible oxixml_xml input sources.
103    ///
104    /// Typically it is more convenient to use one of these methods instead:
105    ///
106    ///  - [`Deserializer::from_str`]
107    ///  - [`Deserializer::from_reader`]
108    pub(crate) fn new(reader: R, entity_resolver: E) -> Self {
109        Self {
110            reader: XmlReader::new(reader, entity_resolver),
111
112            #[cfg(feature = "overlapped-lists")]
113            read: VecDeque::new(),
114            #[cfg(feature = "overlapped-lists")]
115            write: VecDeque::new(),
116            #[cfg(feature = "overlapped-lists")]
117            limit: None,
118
119            #[cfg(not(feature = "overlapped-lists"))]
120            peek: None,
121            #[cfg(not(feature = "overlapped-lists"))]
122            peek2: None,
123
124            key_buf: String::new(),
125        }
126    }
127
128    /// Returns `true` if all events was consumed.
129    pub fn is_empty(&self) -> bool {
130        #[cfg(feature = "overlapped-lists")]
131        let event = self.read.front();
132
133        #[cfg(not(feature = "overlapped-lists"))]
134        let event = self.peek.as_ref();
135
136        match event {
137            None | Some(DeEvent::Eof) => self.reader.is_empty(),
138            _ => false,
139        }
140    }
141
142    /// Returns the underlying XML reader.
143    ///
144    /// ```
145    /// use serde::Deserialize;
146    /// use oxixml_xml::de::Deserializer;
147    /// use oxixml_xml::NsReader;
148    ///
149    /// #[derive(Deserialize)]
150    /// struct SomeStruct {
151    ///     field1: String,
152    ///     field2: String,
153    /// }
154    ///
155    /// // Try to deserialize from broken XML
156    /// let mut de = Deserializer::from_str(
157    ///     "<SomeStruct><field1><field2></SomeStruct>"
158    /// //   0                           ^= 28        ^= 41
159    /// );
160    ///
161    /// let err = SomeStruct::deserialize(&mut de);
162    /// assert!(err.is_err());
163    ///
164    /// let reader: &NsReader<_> = de.get_ref().get_ref();
165    ///
166    /// assert_eq!(reader.error_position(), 28);
167    /// assert_eq!(reader.buffer_position(), 41);
168    /// ```
169    pub const fn get_ref(&self) -> &R {
170        &self.reader.reader
171    }
172
173    /// Set the maximum number of events that could be skipped during deserialization
174    /// of sequences.
175    ///
176    /// If `<element>` contains more than specified nested elements, `$text` or
177    /// CDATA nodes, then [`DeError::TooManyEvents`] will be returned during
178    /// deserialization of sequence field (any type that uses [`deserialize_seq`]
179    /// for the deserialization, for example, `Vec<T>`).
180    ///
181    /// This method can be used to prevent a [DoS] attack and infinite memory
182    /// consumption when parsing a very large XML to a sequence field.
183    ///
184    /// It is strongly recommended to set limit to some value when you parse data
185    /// from untrusted sources. You should choose a value that your typical XMLs
186    /// can have _between_ different elements that corresponds to the same sequence.
187    ///
188    /// # Examples
189    ///
190    /// Let's imagine, that we deserialize such structure:
191    /// ```
192    /// struct List {
193    ///   item: Vec<()>,
194    /// }
195    /// ```
196    ///
197    /// The XML that we try to parse look like this:
198    /// ```xml
199    /// <any-name>
200    ///   <item/>
201    ///   <!-- Bufferization starts at this point -->
202    ///   <another-item>
203    ///     <some-element>with text</some-element>
204    ///     <yet-another-element/>
205    ///   </another-item>
206    ///   <!-- Buffer will be emptied at this point; 7 events were buffered -->
207    ///   <item/>
208    ///   <!-- There is nothing to buffer, because elements follows each other -->
209    ///   <item/>
210    /// </any-name>
211    /// ```
212    ///
213    /// There, when we deserialize the `item` field, we need to buffer 7 events,
214    /// before we can deserialize the second `<item/>`:
215    ///
216    /// - `<another-item>`
217    /// - `<some-element>`
218    /// - `$text(with text)`
219    /// - `</some-element>`
220    /// - `<yet-another-element/>` (virtual start event)
221    /// - `<yet-another-element/>` (virtual end event)
222    /// - `</another-item>`
223    ///
224    /// Note, that `<yet-another-element/>` internally represented as 2 events:
225    /// one for the start tag and one for the end tag. In the future this can be
226    /// eliminated, but for now we use [auto-expanding feature] of a reader,
227    /// because this simplifies deserializer code.
228    ///
229    /// [`deserialize_seq`]: serde::Deserializer::deserialize_seq
230    /// [DoS]: https://en.wikipedia.org/wiki/Denial-of-service_attack
231    /// [auto-expanding feature]: crate::reader::Config::expand_empty_elements
232    #[cfg(feature = "overlapped-lists")]
233    #[cfg_attr(docsrs, doc(cfg(feature = "overlapped-lists")))]
234    pub fn event_buffer_size(&mut self, limit: Option<NonZeroUsize>) -> &mut Self {
235        self.limit = limit;
236        self
237    }
238
239    #[cfg(feature = "overlapped-lists")]
240    pub(crate) fn peek(&mut self) -> Result<&DeEvent<'de>, DeError> {
241        if self.read.is_empty() {
242            self.read.push_front(self.reader.next()?);
243        }
244        if let Some(event) = self.read.front() {
245            return Ok(event);
246        }
247        // SAFETY: `self.read` was filled in the code above.
248        // NOTE: Can be replaced with `unsafe { std::hint::unreachable_unchecked() }`
249        // if unsafe code will be allowed
250        unreachable!()
251    }
252    #[cfg(not(feature = "overlapped-lists"))]
253    pub(crate) fn peek(&mut self) -> Result<&DeEvent<'de>, DeError> {
254        match &mut self.peek {
255            Some(event) => Ok(event),
256            empty_peek @ None => Ok(empty_peek.insert(self.reader.next()?)),
257        }
258    }
259
260    /// Returns the event immediately after the one reported by [`Self::peek()`],
261    /// consuming neither. Returns `None` only if the input ends before a second
262    /// event exists. Used to resolve element shapes that a single event leaves
263    /// ambiguous (a text-only `<tag>text</tag>` versus mixed or nested content).
264    #[cfg(feature = "overlapped-lists")]
265    pub(crate) fn peek_second(&mut self) -> Result<Option<&DeEvent<'de>>, DeError> {
266        while self.read.len() < 2 {
267            let event = self.reader.next()?;
268            let reached_eof = matches!(event, DeEvent::Eof);
269            self.read.push_back(event);
270            if reached_eof {
271                break;
272            }
273        }
274        Ok(self.read.get(1))
275    }
276    #[cfg(not(feature = "overlapped-lists"))]
277    pub(crate) fn peek_second(&mut self) -> Result<Option<&DeEvent<'de>>, DeError> {
278        if self.peek.is_none() {
279            self.peek = Some(self.reader.next()?);
280        }
281        if self.peek2.is_none() {
282            self.peek2 = Some(self.reader.next()?);
283        }
284        Ok(self.peek2.as_ref())
285    }
286
287    #[inline]
288    pub(crate) fn last_peeked(&self) -> &DeEvent<'de> {
289        #[cfg(feature = "overlapped-lists")]
290        {
291            self.read
292                .front()
293                .expect("`Deserializer::peek()` should be called")
294        }
295        #[cfg(not(feature = "overlapped-lists"))]
296        {
297            self.peek
298                .as_ref()
299                .expect("`Deserializer::peek()` should be called")
300        }
301    }
302
303    pub(crate) fn next(&mut self) -> Result<DeEvent<'de>, DeError> {
304        // Replay skipped or peeked events
305        #[cfg(feature = "overlapped-lists")]
306        if let Some(event) = self.read.pop_front() {
307            return Ok(event);
308        }
309        #[cfg(not(feature = "overlapped-lists"))]
310        if let Some(e) = self.peek.take() {
311            // Keep the lookahead contiguous: the second slot becomes the first.
312            self.peek = self.peek2.take();
313            return Ok(e);
314        }
315        self.reader.next()
316    }
317
318    pub(crate) fn skip_whitespaces(&mut self) -> Result<(), DeError> {
319        loop {
320            match self.peek()? {
321                DeEvent::Text(e) if e.is_blank() => {
322                    self.next()?;
323                }
324                _ => break,
325            }
326        }
327        Ok(())
328    }
329
330    /// Returns the mark after which all events, skipped by [`Self::skip()`] call,
331    /// should be replayed after calling [`Self::start_replay()`].
332    #[cfg(feature = "overlapped-lists")]
333    #[inline]
334    #[must_use = "returned checkpoint should be used in `start_replay`"]
335    pub(crate) fn skip_checkpoint(&self) -> usize {
336        self.write.len()
337    }
338
339    /// Extracts XML tree of events from and stores them in the skipped events
340    /// buffer from which they can be retrieved later. You MUST call
341    /// [`Self::start_replay()`] after calling this to give access to the skipped
342    /// events and release internal buffers.
343    #[cfg(feature = "overlapped-lists")]
344    pub(crate) fn skip(&mut self) -> Result<(), DeError> {
345        let event = self.next()?;
346        self.skip_event(event)?;
347        // Skip all subtree, if we skip a start event
348        if let Some(DeEvent::Start(e)) = self.write.back() {
349            let end = e.name().as_ref().to_owned();
350            let mut depth = 0;
351            loop {
352                let event = self.next()?;
353                match event {
354                    DeEvent::Start(ref e) if e.name().as_ref() == end => {
355                        self.skip_event(event)?;
356                        depth += 1;
357                    }
358                    DeEvent::End(ref e) if e.name().as_ref() == end => {
359                        self.skip_event(event)?;
360                        if depth == 0 {
361                            break;
362                        }
363                        depth -= 1;
364                    }
365                    DeEvent::Eof => {
366                        self.skip_event(event)?;
367                        break;
368                    }
369                    _ => self.skip_event(event)?,
370                }
371            }
372        }
373        Ok(())
374    }
375
376    #[cfg(feature = "overlapped-lists")]
377    #[inline]
378    pub(crate) fn skip_event(&mut self, event: DeEvent<'de>) -> Result<(), DeError> {
379        if let Some(max) = self.limit {
380            if self.write.len() >= max.get() {
381                return Err(DeError::TooManyEvents(max));
382            }
383        }
384        self.write.push_back(event);
385        Ok(())
386    }
387
388    /// Moves buffered events, skipped after given `checkpoint` from [`Self::write`]
389    /// skip buffer to [`Self::read`] buffer.
390    ///
391    /// After calling this method, [`Self::peek()`] and [`Self::next()`] starts
392    /// return events that was skipped previously by calling [`Self::skip()`],
393    /// and only when all that events will be consumed, the deserializer starts
394    /// to drain events from underlying reader.
395    ///
396    /// This method MUST be called if any number of [`Self::skip()`] was called
397    /// after [`Self::new()`] or `start_replay()` or you'll lost events.
398    #[cfg(feature = "overlapped-lists")]
399    pub(crate) fn start_replay(&mut self, checkpoint: usize) {
400        if checkpoint == 0 {
401            self.write.append(&mut self.read);
402            std::mem::swap(&mut self.read, &mut self.write);
403        } else {
404            let mut read = self.write.split_off(checkpoint);
405            read.append(&mut self.read);
406            self.read = read;
407        }
408    }
409
410    #[inline]
411    pub(crate) fn read_string(&mut self) -> Result<Cow<'de, str>, DeError> {
412        self.read_string_impl(true)
413    }
414
415    /// Consumes consequent [`Text`] and [`CData`] (both a referred below as a _text_)
416    /// events, merge them into one string. If there are no such events, returns
417    /// an empty string.
418    ///
419    /// If `allow_start` is `false`, then only text events are consumed, for other
420    /// events an error is returned (see table below).
421    ///
422    /// If `allow_start` is `true`, then two or three events are expected:
423    /// - [`DeEvent::Start`];
424    /// - _(optional)_ [`DeEvent::Text`] which content is returned;
425    /// - [`DeEvent::End`]. If text event was missed, an empty string is returned.
426    ///
427    /// Corresponding events are consumed.
428    ///
429    /// # Handling events
430    ///
431    /// The table below shows how events is handled by this method:
432    ///
433    /// |Event             |XML                        |Handling
434    /// |------------------|---------------------------|----------------------------------------
435    /// |[`DeEvent::Start`]|`<tag>...</tag>`           |if `allow_start == true`, result determined by the second table, otherwise emits [`UnexpectedStart("tag")`](DeError::UnexpectedStart)
436    /// |[`DeEvent::End`]  |`</any-tag>`               |Normally impossible, the reader guarantees tags are balanced; reachable only when [`Config::allow_unmatched_ends`] is set, in which case emits [`InvalidXml`](DeError::InvalidXml) wrapping [`UnmatchedEndTag`](crate::errors::IllFormedError::UnmatchedEndTag)
437    /// |[`DeEvent::Text`] |`text content` or `<![CDATA[cdata content]]>` (probably mixed)|Returns event content unchanged
438    /// |[`DeEvent::Eof`]  |                           |Emits [`UnexpectedEof`](DeError::UnexpectedEof)
439    ///
440    /// [`Config::allow_unmatched_ends`]: crate::reader::Config::allow_unmatched_ends
441    ///
442    /// Second event, consumed if [`DeEvent::Start`] was received and `allow_start == true`:
443    ///
444    /// |Event             |XML                        |Handling
445    /// |------------------|---------------------------|----------------------------------------------------------------------------------
446    /// |[`DeEvent::Start`]|`<any-tag>...</any-tag>`   |Emits [`UnexpectedStart("any-tag")`](DeError::UnexpectedStart)
447    /// |[`DeEvent::End`]  |`</tag>`                   |Returns an empty slice. The reader guarantee that tag will match the open one
448    /// |[`DeEvent::Text`] |`text content` or `<![CDATA[cdata content]]>` (probably mixed)|Returns event content unchanged, expects the `</tag>` after that
449    /// |[`DeEvent::Eof`]  |                           |Emits [`InvalidXml(IllFormed(MissingEndTag))`](DeError::InvalidXml)
450    ///
451    /// [`Text`]: Event::Text
452    /// [`CData`]: Event::CData
453    pub(crate) fn read_string_impl(&mut self, allow_start: bool) -> Result<Cow<'de, str>, DeError> {
454        match self.next()? {
455            // Reached by doc tests only: this file, lines 979 and 996
456            DeEvent::Text(e) => Ok(e.text),
457            // allow one nested level
458            // Reached by trivial::{...}::{field, field_nested, field_tag_after, field_tag_before, nested, tag_after, tag_before, wrapped}
459            DeEvent::Start(e) if allow_start => self.read_text(e.name()),
460            // Reached by `value_field_rejects_nested_element` in tests/serde-de.rs:
461            // a `$value`-typed primitive field whose position in the document holds
462            // a nested element instead of text.
463            DeEvent::Start(e) => Err(DeError::UnexpectedStart(e.name().as_ref().to_owned())),
464            // Only reachable when `Config::allow_unmatched_ends` lets the reader emit
465            // an `End` with no matching `Start` anywhere in the document; report it the
466            // same way the reader itself would if that option were off.
467            DeEvent::End(e) => Err(Error::unmatched_end(e.name(), self.reader.decoder()).into()),
468            // Reached by trivial::{empty_doc, only_comment}
469            DeEvent::Eof => Err(DeError::UnexpectedEof),
470        }
471    }
472    /// Consumes one [`DeEvent::Text`] event and ensures that it is followed by the
473    /// [`DeEvent::End`] event.
474    ///
475    /// # Parameters
476    /// - `name`: name of a tag opened before reading text. The corresponding end tag
477    ///   should present in input just after the text
478    pub(crate) fn read_text(&mut self, name: QName) -> Result<Cow<'de, str>, DeError> {
479        match self.next()? {
480            DeEvent::Text(e) => match self.next()? {
481                // The matching tag name is guaranteed by the reader
482                // Reached by trivial::{...}::{field, wrapped}
483                DeEvent::End(_) => Ok(e.text),
484                // SAFETY: Cannot be two consequent Text events, they would be merged into one
485                DeEvent::Text(_) => unreachable!(),
486                // Reached by trivial::{...}::{field_tag_after, tag_after}
487                DeEvent::Start(e) => Err(DeError::UnexpectedStart(e.name().as_ref().to_owned())),
488                // Reached by struct_::non_closed::elements_child
489                DeEvent::Eof => Err(Error::missed_end(name, self.reader.decoder()).into()),
490            },
491            // We can get End event in case of `<tag></tag>` or `<tag/>` input
492            // Return empty text in that case
493            // The matching tag name is guaranteed by the reader
494            // Reached by {...}::xs_list::empty
495            DeEvent::End(_) => Ok("".into()),
496            // Reached by trivial::{...}::{field_nested, field_tag_before, nested, tag_before}
497            DeEvent::Start(s) => Err(DeError::UnexpectedStart(s.name().as_ref().to_owned())),
498            // Reached by struct_::non_closed::elements_child
499            DeEvent::Eof => Err(Error::missed_end(name, self.reader.decoder()).into()),
500        }
501    }
502
503    /// Drops all events until event with [name](BytesEnd::name()) `name` won't be
504    /// dropped. This method should be called after [`Self::next()`]
505    #[cfg(feature = "overlapped-lists")]
506    pub(crate) fn read_to_end(&mut self, name: QName) -> Result<(), DeError> {
507        let mut depth = 0;
508        loop {
509            match self.read.pop_front() {
510                Some(DeEvent::Start(e)) if e.name() == name => {
511                    depth += 1;
512                }
513                Some(DeEvent::End(e)) if e.name() == name => {
514                    if depth == 0 {
515                        break;
516                    }
517                    depth -= 1;
518                }
519
520                // Drop all other skipped events
521                Some(_) => continue,
522
523                // If we do not have skipped events, use effective reading that will
524                // not allocate memory for events
525                None => {
526                    // We should close all opened tags, because we could buffer
527                    // Start events, but not the corresponding End events. So we
528                    // keep reading events until we exit all nested tags.
529                    // `read_to_end()` will return an error if an Eof was encountered
530                    // preliminary (in case of malformed XML).
531                    //
532                    // <tag><tag></tag></tag>
533                    // ^^^^^^^^^^             - buffered in `self.read`, when `self.read_to_end()` is called, depth = 2
534                    //           ^^^^^^       - read by the first call of `self.reader.read_to_end()`
535                    //                 ^^^^^^ - read by the second call of `self.reader.read_to_end()`
536                    loop {
537                        self.reader.read_to_end(name)?;
538                        if depth == 0 {
539                            break;
540                        }
541                        depth -= 1;
542                    }
543                    break;
544                }
545            }
546        }
547        Ok(())
548    }
549    #[cfg(not(feature = "overlapped-lists"))]
550    pub(crate) fn read_to_end(&mut self, name: QName) -> Result<(), DeError> {
551        // First one might be in self.peek
552        match self.next()? {
553            DeEvent::Start(e) => self.reader.read_to_end(e.name())?,
554            DeEvent::End(e) if e.name() == name => return Ok(()),
555            _ => (),
556        }
557        self.reader.read_to_end(name)
558    }
559
560    pub(crate) fn skip_next_tree(&mut self) -> Result<(), DeError> {
561        let DeEvent::Start(start) = self.next()? else {
562            unreachable!("Only call this if the next event is a start event")
563        };
564        let name = start.name();
565        self.read_to_end(name)
566    }
567
568    /// Method for testing Deserializer implementation. Checks that all events was consumed during
569    /// deserialization. Panics if the next event will not be [`DeEvent::Eof`].
570    #[doc(hidden)]
571    #[track_caller]
572    pub fn check_eof_reached(&mut self) {
573        // Deserializer may not consume trailing spaces, that is normal
574        self.skip_whitespaces().expect("cannot skip whitespaces");
575        let event = self.peek().expect("cannot peek event");
576        assert_eq!(
577            *event,
578            DeEvent::Eof,
579            "the whole XML document should be consumed, expected `Eof`",
580        );
581    }
582}
583
584impl<'de> Deserializer<'de, SliceReader<'de>> {
585    /// Create a new deserializer that will borrow data from the specified string.
586    ///
587    /// Deserializer created with this method will not resolve custom entities.
588    #[allow(clippy::should_implement_trait)]
589    pub fn from_str(source: &'de str) -> Self {
590        Self::from_str_with_resolver(source, PredefinedEntityResolver)
591    }
592
593    /// Create a new deserializer that will borrow data from the specified preconfigured
594    /// reader.
595    ///
596    /// Deserializer created with this method will not resolve custom entities.
597    ///
598    /// Note, that config option [`Config::expand_empty_elements`] will be set to `true`.
599    ///
600    /// # Example
601    ///
602    /// ```
603    /// # use oxixml_xml::de::Deserializer;
604    /// # use oxixml_xml::NsReader;
605    /// # use serde::Deserialize;
606    /// #
607    /// #[derive(Deserialize, PartialEq, Debug)]
608    /// struct Object<'a> {
609    ///     tag: &'a str,
610    /// }
611    ///
612    /// let mut reader = NsReader::from_str("<xml><tag>    test    </tag></xml>");
613    ///
614    /// let mut de = Deserializer::borrowing(reader.clone());
615    /// let obj = Object::deserialize(&mut de).expect("should be Ok");
616    /// assert_eq!(obj, Object { tag: "    test    " });
617    ///
618    /// reader.config_mut().trim_text(true);
619    ///
620    /// let mut de = Deserializer::borrowing(reader);
621    /// let obj = Object::deserialize(&mut de).expect("should be Ok");
622    /// assert_eq!(obj, Object { tag: "test" });
623    /// ```
624    ///
625    /// [`Config::expand_empty_elements`]: crate::reader::Config::expand_empty_elements
626    #[inline]
627    pub fn borrowing(reader: NsReader<&'de [u8]>) -> Self {
628        Self::borrowing_with_resolver(reader, PredefinedEntityResolver)
629    }
630}
631
632impl<'de, E> Deserializer<'de, SliceReader<'de>, E>
633where
634    E: EntityResolver,
635{
636    /// Create a new deserializer that will borrow data from the specified string
637    /// and use the specified entity resolver.
638    pub fn from_str_with_resolver(source: &'de str, entity_resolver: E) -> Self {
639        Self::borrowing_with_resolver(NsReader::from_str(source), entity_resolver)
640    }
641
642    /// Create a new deserializer that will borrow data from the specified preconfigured
643    /// reader and use the specified entity resolver.
644    ///
645    /// Note, that config option [`Config::expand_empty_elements`] will be set to `true`.
646    ///
647    /// [`Config::expand_empty_elements`]: crate::reader::Config::expand_empty_elements
648    pub fn borrowing_with_resolver(mut reader: NsReader<&'de [u8]>, entity_resolver: E) -> Self {
649        let config = reader.config_mut();
650        config.expand_empty_elements = true;
651
652        Self::new(
653            SliceReader {
654                reader,
655                version: XmlVersion::Implicit1_0,
656            },
657            entity_resolver,
658        )
659    }
660}
661
662impl<'de, R> Deserializer<'de, IoReader<R>>
663where
664    R: BufRead,
665{
666    /// Create a new deserializer that will copy data from the specified reader
667    /// into internal buffer.
668    ///
669    /// If you already have a string use [`Self::from_str`] instead, because it
670    /// will borrow instead of copy. If you have `&[u8]` which is known to represent
671    /// UTF-8, you can decode it first before using [`from_str`].
672    ///
673    /// Deserializer created with this method will not resolve custom entities.
674    pub fn from_reader(reader: R) -> Self {
675        Self::with_resolver(reader, PredefinedEntityResolver)
676    }
677
678    /// Create a new deserializer that will copy data from the specified preconfigured
679    /// reader into internal buffer.
680    ///
681    /// Deserializer created with this method will not resolve custom entities.
682    ///
683    /// Note, that config option [`Config::expand_empty_elements`] will be set to `true`.
684    ///
685    /// # Example
686    ///
687    /// ```
688    /// # use oxixml_xml::de::Deserializer;
689    /// # use oxixml_xml::NsReader;
690    /// # use serde::Deserialize;
691    /// #
692    /// #[derive(Deserialize, PartialEq, Debug)]
693    /// struct Object {
694    ///     tag: String,
695    /// }
696    ///
697    /// let mut reader = NsReader::from_str("<xml><tag>    test    </tag></xml>");
698    ///
699    /// let mut de = Deserializer::buffering(reader.clone());
700    /// let obj = Object::deserialize(&mut de).expect("should be Ok");
701    /// assert_eq!(obj, Object { tag: "    test    ".to_string() });
702    ///
703    /// reader.config_mut().trim_text(true);
704    ///
705    /// let mut de = Deserializer::buffering(reader);
706    /// let obj = Object::deserialize(&mut de).expect("should be Ok");
707    /// assert_eq!(obj, Object { tag: "test".to_string() });
708    /// ```
709    ///
710    /// [`Config::expand_empty_elements`]: crate::reader::Config::expand_empty_elements
711    #[inline]
712    pub fn buffering(reader: NsReader<R>) -> Self {
713        Self::buffering_with_resolver(reader, PredefinedEntityResolver)
714    }
715}
716
717impl<'de, R, E> Deserializer<'de, IoReader<R>, E>
718where
719    R: BufRead,
720    E: EntityResolver,
721{
722    /// Create a new deserializer that will copy data from the specified reader
723    /// into internal buffer and use the specified entity resolver.
724    ///
725    /// If you already have a string use [`Self::from_str`] instead, because it
726    /// will borrow instead of copy. If you have `&[u8]` which is known to represent
727    /// UTF-8, you can decode it first before using [`from_str`].
728    pub fn with_resolver(reader: R, entity_resolver: E) -> Self {
729        let mut reader = NsReader::from_reader(reader);
730        let config = reader.config_mut();
731        config.expand_empty_elements = true;
732
733        Self::new(
734            IoReader {
735                reader,
736                buf: Vec::new(),
737                version: XmlVersion::Implicit1_0,
738            },
739            entity_resolver,
740        )
741    }
742
743    /// Create new deserializer that will copy data from the specified preconfigured reader
744    /// into internal buffer and use the specified entity resolver.
745    ///
746    /// Note, that config option [`Config::expand_empty_elements`] will be set to `true`.
747    ///
748    /// [`Config::expand_empty_elements`]: crate::reader::Config::expand_empty_elements
749    pub fn buffering_with_resolver(mut reader: NsReader<R>, entity_resolver: E) -> Self {
750        let config = reader.config_mut();
751        config.expand_empty_elements = true;
752
753        Self::new(
754            IoReader {
755                reader,
756                buf: Vec::new(),
757                version: XmlVersion::Implicit1_0,
758            },
759            entity_resolver,
760        )
761    }
762}
763
764impl<'de, R, E> de::Deserializer<'de> for &mut Deserializer<'de, R, E>
765where
766    R: XmlRead<'de>,
767    E: EntityResolver,
768{
769    type Error = DeError;
770
771    deserialize_primitives!();
772
773    fn deserialize_struct<V>(
774        self,
775        _name: &'static str,
776        fields: &'static [&'static str],
777        visitor: V,
778    ) -> Result<V::Value, DeError>
779    where
780        V: Visitor<'de>,
781    {
782        // When document is pretty-printed there could be whitespaces before the root element
783        self.skip_whitespaces()?;
784        match self.next()? {
785            DeEvent::Start(e) => visitor.visit_map(ElementMapAccess::new(self, e, fields)),
786            // Normally impossible, the reader guarantees tags are balanced; reachable
787            // only when `Config::allow_unmatched_ends` lets a stray closing tag through.
788            DeEvent::End(e) => Err(Error::unmatched_end(e.name(), self.reader.decoder()).into()),
789            // Deserializer methods are only hints, if deserializer could not satisfy
790            // request, it should return the data that it has. It is responsibility
791            // of a Visitor to return an error if it does not understand the data
792            DeEvent::Text(e) => match e.text {
793                Cow::Borrowed(s) => visitor.visit_borrowed_str(s),
794                Cow::Owned(s) => visitor.visit_string(s),
795            },
796            DeEvent::Eof => Err(DeError::UnexpectedEof),
797        }
798    }
799
800    /// Unit represented in XML as a `xs:element` or text/CDATA content.
801    /// Any content inside `xs:element` is ignored and skipped.
802    ///
803    /// Produces unit struct from any of following inputs:
804    /// - any `<tag ...>...</tag>`
805    /// - any `<tag .../>`
806    /// - any consequent text / CDATA content (can consist of several parts
807    ///   delimited by comments and processing instructions)
808    ///
809    /// # Events handling
810    ///
811    /// |Event             |XML                        |Handling
812    /// |------------------|---------------------------|-------------------------------------------
813    /// |[`DeEvent::Start`]|`<tag>...</tag>`           |Calls `visitor.visit_unit()`, consumes all events up to and including corresponding `End` event
814    /// |[`DeEvent::End`]  |`</tag>`                   |Normally impossible, the reader guarantees tags are balanced; reachable only when [`Config::allow_unmatched_ends`] is set, in which case emits [`InvalidXml`](DeError::InvalidXml) wrapping [`UnmatchedEndTag`](crate::errors::IllFormedError::UnmatchedEndTag)
815    /// |[`DeEvent::Text`] |`text content` or `<![CDATA[cdata content]]>` (probably mixed)|Calls `visitor.visit_unit()`. The content is ignored
816    /// |[`DeEvent::Eof`]  |                           |Emits [`UnexpectedEof`](DeError::UnexpectedEof)
817    ///
818    /// [`Config::allow_unmatched_ends`]: crate::reader::Config::allow_unmatched_ends
819    fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, DeError>
820    where
821        V: Visitor<'de>,
822    {
823        match self.next()? {
824            DeEvent::Start(s) => {
825                self.read_to_end(s.name())?;
826                visitor.visit_unit()
827            }
828            DeEvent::Text(_) => visitor.visit_unit(),
829            // Normally impossible, the reader guarantees tags are balanced; reachable
830            // only when `Config::allow_unmatched_ends` lets a stray closing tag through.
831            DeEvent::End(e) => Err(Error::unmatched_end(e.name(), self.reader.decoder()).into()),
832            DeEvent::Eof => Err(DeError::UnexpectedEof),
833        }
834    }
835
836    /// Forwards deserialization of the inner type. Always calls [`Visitor::visit_newtype_struct`]
837    /// with the same deserializer.
838    fn deserialize_newtype_struct<V>(
839        self,
840        _name: &'static str,
841        visitor: V,
842    ) -> Result<V::Value, DeError>
843    where
844        V: Visitor<'de>,
845    {
846        visitor.visit_newtype_struct(self)
847    }
848
849    fn deserialize_enum<V>(
850        self,
851        _name: &'static str,
852        _variants: &'static [&'static str],
853        visitor: V,
854    ) -> Result<V::Value, DeError>
855    where
856        V: Visitor<'de>,
857    {
858        // When document is pretty-printed there could be whitespaces before the root element
859        // which represents the enum variant
860        // Checked by `top_level::list_of_enum` test in serde-de-seq
861        self.skip_whitespaces()?;
862        visitor.visit_enum(var::EnumAccess::new(self))
863    }
864
865    fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, DeError>
866    where
867        V: Visitor<'de>,
868    {
869        visitor.visit_seq(self)
870    }
871
872    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, DeError>
873    where
874        V: Visitor<'de>,
875    {
876        // We cannot use result of `peek()` directly because of borrow checker
877        let _ = self.peek()?;
878        match self.last_peeked() {
879            DeEvent::Text(t) if t.is_empty() => visitor.visit_none(),
880            DeEvent::Eof => visitor.visit_none(),
881            // if the `xsi:nil` attribute is set to true we got a none value
882            DeEvent::Start(start) if self.reader.reader.has_nil_attr(start) => {
883                self.skip_next_tree()?;
884                visitor.visit_none()
885            }
886            _ => visitor.visit_some(self),
887        }
888    }
889
890    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, DeError>
891    where
892        V: Visitor<'de>,
893    {
894        match self.peek()? {
895            DeEvent::Text(_) => self.deserialize_str(visitor),
896            _ => self.deserialize_map(visitor),
897        }
898    }
899}
900
901/// An accessor to sequence elements forming a value for top-level sequence of XML
902/// elements.
903///
904/// Technically, multiple top-level elements violates XML rule of only one top-level
905/// element, but we consider this as several concatenated XML documents.
906impl<'de, R, E> SeqAccess<'de> for &mut Deserializer<'de, R, E>
907where
908    R: XmlRead<'de>,
909    E: EntityResolver,
910{
911    type Error = DeError;
912
913    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
914    where
915        T: DeserializeSeed<'de>,
916    {
917        // When document is pretty-printed there could be whitespaces before, between
918        // and after root elements. We cannot defer decision if we need to skip spaces
919        // or not: if we have a sequence of type that does not accept blank text, it
920        // will need to return something and it can return only error. For example,
921        // it can be enum without `$text` variant
922        // Checked by `top_level::list_of_enum` test in serde-de-seq
923        self.skip_whitespaces()?;
924        match self.peek()? {
925            DeEvent::Eof => Ok(None),
926
927            // Start(tag), End(tag), Text
928            _ => seed.deserialize(&mut **self).map(Some),
929        }
930    }
931}
932
933impl<'de, R, E> IntoDeserializer<'de, DeError> for &mut Deserializer<'de, R, E>
934where
935    R: XmlRead<'de>,
936    E: EntityResolver,
937{
938    type Deserializer = Self;
939
940    #[inline]
941    fn into_deserializer(self) -> Self {
942        self
943    }
944}