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