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}