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}