1//! Serde `Deserializer` module
2
3use crate::{
4 de::key::QNameDeserializer,
5 de::resolver::EntityResolver,
6 de::simple_type::SimpleTypeDeserializer,
7 de::{str2bool, DeEvent, Deserializer, XmlRead, TEXT_KEY, VALUE_KEY},
8 encoding::Decoder,
9 errors::serialize::DeError,
10 events::attributes::IterState,
11 events::BytesStart,
12 name::QName,
13};
14use serde::de::value::BorrowedStrDeserializer;
15use serde::de::{self, DeserializeSeed, SeqAccess, Visitor};
16use serde::serde_if_integer128;
17use std::borrow::Cow;
18use std::ops::Range;
19
20/// Defines a source that should be used to deserialize a value in the next call
21/// to [`next_value_seed()`](de::MapAccess::next_value_seed)
22#[derive(Debug, PartialEq)]
23enum ValueSource {
24 /// Source are not specified, because [`next_key_seed()`] not yet called.
25 /// This is an initial state and state after deserializing value
26 /// (after call of [`next_value_seed()`]).
27 ///
28 /// Attempt to call [`next_value_seed()`] while accessor in this state would
29 /// return a [`DeError::KeyNotRead`] error.
30 ///
31 /// [`next_key_seed()`]: de::MapAccess::next_key_seed
32 /// [`next_value_seed()`]: de::MapAccess::next_value_seed
33 Unknown,
34 /// Next value should be deserialized from an attribute value; value is located
35 /// at specified span.
36 Attribute(Range<usize>),
37 /// Value should be deserialized from the text content of the XML node, which
38 /// represented or by an ordinary text node, or by a CDATA node:
39 ///
40 /// ```xml
41 /// <any-tag>
42 /// <key>text content</key>
43 /// <!-- ^^^^^^^^^^^^ - this will be used to deserialize map value -->
44 /// </any-tag>
45 /// ```
46 /// ```xml
47 /// <any-tag>
48 /// <key><![CDATA[cdata content]]></key>
49 /// <!-- ^^^^^^^^^^^^^ - this will be used to deserialize a map value -->
50 /// </any-tag>
51 /// ```
52 Text,
53 /// Next value should be deserialized from an element with an any name, except
54 /// elements with a name matching one of the struct fields. Corresponding tag
55 /// name will always be associated with a field with name [`VALUE_KEY`].
56 ///
57 /// That state is set when call to [`peek()`] returns a [`Start`] event, which
58 /// [`name()`] is not listed in the [list of known fields] (which for a struct
59 /// is a list of field names, and for a map that is an empty list), _and_
60 /// struct has a field with a special name [`VALUE_KEY`].
61 ///
62 /// When in this state, next event, returned by [`next()`], will be a [`Start`],
63 /// which represents both a key, and a value. Value would be deserialized from
64 /// the whole element and how is will be done determined by the value deserializer.
65 /// The [`MapAccess`] do not consume any events in that state.
66 ///
67 /// Because in that state any encountered `<tag>` is mapped to the [`VALUE_KEY`]
68 /// field, it is possible to use tag name as an enum discriminator, so `enum`s
69 /// can be deserialized from that XMLs:
70 ///
71 /// ```xml
72 /// <any-tag>
73 /// <variant1>...</variant1>
74 /// <!-- ~~~~~~~~ - this data will determine that this is Enum::variant1 -->
75 /// <!--^^^^^^^^^^^^^^^^^^^^^^^ - this data will be used to deserialize a map value -->
76 /// </any-tag>
77 /// ```
78 /// ```xml
79 /// <any-tag>
80 /// <variant2>...</variant2>
81 /// <!-- ~~~~~~~~ - this data will determine that this is Enum::variant2 -->
82 /// <!--^^^^^^^^^^^^^^^^^^^^^^^ - this data will be used to deserialize a map value -->
83 /// </any-tag>
84 /// ```
85 ///
86 /// both can be deserialized into
87 ///
88 /// ```ignore
89 /// enum Enum {
90 /// variant1,
91 /// variant2,
92 /// }
93 /// struct AnyName {
94 /// #[serde(rename = "$value")]
95 /// field: Enum,
96 /// }
97 /// ```
98 ///
99 /// That is possible, because value deserializer have access to the full content
100 /// of a `<variant1>...</variant1>` or `<variant2>...</variant2>` node, including
101 /// the tag name.
102 ///
103 /// [`Start`]: DeEvent::Start
104 /// [`peek()`]: Deserializer::peek()
105 /// [`next()`]: Deserializer::next()
106 /// [`name()`]: BytesStart::name()
107 /// [`Text`]: Self::Text
108 /// [list of known fields]: MapAccess::fields
109 Content,
110 /// Next value should be deserialized from an element with a dedicated name.
111 /// If deserialized type is a sequence, then that sequence will collect all
112 /// elements with the same name until it will be filled. If not all elements
113 /// would be consumed, the rest will be ignored.
114 ///
115 /// That state is set when call to [`peek()`] returns a [`Start`] event, which
116 /// [`name()`] represents a field name. That name will be deserialized as a key.
117 ///
118 /// When in this state, next event, returned by [`next()`], will be a [`Start`],
119 /// which represents both a key, and a value. Value would be deserialized from
120 /// the whole element and how is will be done determined by the value deserializer.
121 /// The [`MapAccess`] do not consume any events in that state.
122 ///
123 /// An illustration below shows, what data is used to deserialize key and value:
124 /// ```xml
125 /// <any-tag>
126 /// <key>...</key>
127 /// <!-- ~~~ - this data will be used to deserialize a map key -->
128 /// <!--^^^^^^^^^^^^^^ - this data will be used to deserialize a map value -->
129 /// </any-tag>
130 /// ```
131 ///
132 /// Although value deserializer will have access to the full content of a `<key>`
133 /// node (including the tag name), it will not get much benefits from that,
134 /// because tag name will always be fixed for a given map field (equal to a
135 /// field name). So, if the field type is an `enum`, it cannot select its
136 /// variant based on the tag name. If that is needed, then [`Content`] variant
137 /// of this enum should be used. Such usage is enabled by annotating a struct
138 /// field as "content" field, which implemented as given the field a special
139 /// [`VALUE_KEY`] name.
140 ///
141 /// [`Start`]: DeEvent::Start
142 /// [`peek()`]: Deserializer::peek()
143 /// [`next()`]: Deserializer::next()
144 /// [`name()`]: BytesStart::name()
145 /// [`Content`]: Self::Content
146 Nested,
147}
148
149////////////////////////////////////////////////////////////////////////////////////////////////////
150
151/// A deserializer that extracts map-like structures from an XML. This deserializer
152/// represents a one XML tag:
153///
154/// ```xml
155/// <tag>...</tag>
156/// ```
157///
158/// Name of this tag is stored in a [`Self::start`] property.
159///
160/// # Lifetimes
161///
162/// - `'de` lifetime represents a buffer, from which deserialized values can
163/// borrow their data. Depending on the underlying reader, there can be an
164/// internal buffer of deserializer (i.e. deserializer itself) or an input
165/// (in that case it is possible to approach zero-copy deserialization).
166///
167/// - `'a` lifetime represents a parent deserializer, which could own the data
168/// buffer.
169pub(crate) struct MapAccess<'de, 'a, R, E>
170where
171 R: XmlRead<'de>,
172 E: EntityResolver,
173{
174 /// Tag -- owner of attributes
175 start: BytesStart<'de>,
176 de: &'a mut Deserializer<'de, R, E>,
177 /// State of the iterator over attributes. Contains the next position in the
178 /// inner `start` slice, from which next attribute should be parsed.
179 iter: IterState,
180 /// Current state of the accessor that determines what next call to API
181 /// methods should return.
182 source: ValueSource,
183 /// List of field names of the struct. It is empty for maps
184 fields: &'static [&'static str],
185 /// If `true`, then the deserialized struct has a field with a special name:
186 /// [`VALUE_KEY`]. That field should be deserialized from the whole content
187 /// of an XML node, including tag name:
188 ///
189 /// ```xml
190 /// <tag>value for VALUE_KEY field<tag>
191 /// ```
192 has_value_field: bool,
193}
194
195impl<'de, 'a, R, E> MapAccess<'de, 'a, R, E>
196where
197 R: XmlRead<'de>,
198 E: EntityResolver,
199{
200 /// Create a new MapAccess
201 pub fn new(
202 de: &'a mut Deserializer<'de, R, E>,
203 start: BytesStart<'de>,
204 fields: &'static [&'static str],
205 ) -> Result<Self, DeError> {
206 Ok(MapAccess {
207 de,
208 iter: IterState::new(offset:start.name().as_ref().len(), html:false),
209 start,
210 source: ValueSource::Unknown,
211 fields,
212 has_value_field: fields.contains(&VALUE_KEY),
213 })
214 }
215}
216
217impl<'de, 'a, R, E> de::MapAccess<'de> for MapAccess<'de, 'a, R, E>
218where
219 R: XmlRead<'de>,
220 E: EntityResolver,
221{
222 type Error = DeError;
223
224 fn next_key_seed<K: DeserializeSeed<'de>>(
225 &mut self,
226 seed: K,
227 ) -> Result<Option<K::Value>, Self::Error> {
228 debug_assert_eq!(self.source, ValueSource::Unknown);
229
230 // FIXME: There error positions counted from the start of tag name - need global position
231 let slice = &self.start.buf;
232 let decoder = self.de.reader.decoder();
233
234 if let Some(a) = self.iter.next(slice).transpose()? {
235 // try getting map from attributes (key= "value")
236 let (key, value) = a.into();
237 self.source = ValueSource::Attribute(value.unwrap_or_default());
238
239 let de = QNameDeserializer::from_attr(QName(&slice[key]), decoder)?;
240 seed.deserialize(de).map(Some)
241 } else {
242 // try getting from events (<key>value</key>)
243 match self.de.peek()? {
244 // We shouldn't have both `$value` and `$text` fields in the same
245 // struct, so if we have `$value` field, the we should deserialize
246 // text content to `$value`
247 DeEvent::Text(_) if self.has_value_field => {
248 self.source = ValueSource::Content;
249 // Deserialize `key` from special attribute name which means
250 // that value should be taken from the text content of the
251 // XML node
252 let de = BorrowedStrDeserializer::<DeError>::new(VALUE_KEY);
253 seed.deserialize(de).map(Some)
254 }
255 DeEvent::Text(_) => {
256 self.source = ValueSource::Text;
257 // Deserialize `key` from special attribute name which means
258 // that value should be taken from the text content of the
259 // XML node
260 let de = BorrowedStrDeserializer::<DeError>::new(TEXT_KEY);
261 seed.deserialize(de).map(Some)
262 }
263 // Used to deserialize collections of enums, like:
264 // <root>
265 // <A/>
266 // <B/>
267 // <C/>
268 // </root>
269 //
270 // into
271 //
272 // enum Enum { A, B, ะก }
273 // struct Root {
274 // #[serde(rename = "$value")]
275 // items: Vec<Enum>,
276 // }
277 // TODO: This should be handled by #[serde(flatten)]
278 // See https://github.com/serde-rs/serde/issues/1905
279 DeEvent::Start(e) if self.has_value_field && not_in(self.fields, e, decoder)? => {
280 self.source = ValueSource::Content;
281
282 let de = BorrowedStrDeserializer::<DeError>::new(VALUE_KEY);
283 seed.deserialize(de).map(Some)
284 }
285 DeEvent::Start(e) => {
286 self.source = ValueSource::Nested;
287
288 let de = QNameDeserializer::from_elem(e.raw_name(), decoder)?;
289 seed.deserialize(de).map(Some)
290 }
291 // Stop iteration after reaching a closing tag
292 DeEvent::End(e) if e.name() == self.start.name() => Ok(None),
293 // This is a unmatched closing tag, so the XML is invalid
294 DeEvent::End(e) => Err(DeError::UnexpectedEnd(e.name().as_ref().to_owned())),
295 // We cannot get `Eof` legally, because we always inside of the
296 // opened tag `self.start`
297 DeEvent::Eof => Err(DeError::UnexpectedEof),
298 }
299 }
300 }
301
302 fn next_value_seed<K: DeserializeSeed<'de>>(
303 &mut self,
304 seed: K,
305 ) -> Result<K::Value, Self::Error> {
306 match std::mem::replace(&mut self.source, ValueSource::Unknown) {
307 ValueSource::Attribute(value) => seed.deserialize(SimpleTypeDeserializer::from_part(
308 &self.start.buf,
309 value,
310 true,
311 self.de.reader.decoder(),
312 )),
313 // This arm processes the following XML shape:
314 // <any-tag>
315 // text value
316 // </any-tag>
317 // The whole map represented by an `<any-tag>` element, the map key
318 // is implicit and equals to the `TEXT_KEY` constant, and the value
319 // is a `Text` event (the value deserializer will see that event)
320 // This case are checked by "xml_schema_lists::element" tests in tests/serde-de.rs
321 ValueSource::Text => match self.de.next()? {
322 DeEvent::Text(e) => seed.deserialize(SimpleTypeDeserializer::from_text_content(e)),
323 // SAFETY: We set `Text` only when we seen `Text`
324 _ => unreachable!(),
325 },
326 // This arm processes the following XML shape:
327 // <any-tag>
328 // <any>...</any>
329 // </any-tag>
330 // The whole map represented by an `<any-tag>` element, the map key
331 // is implicit and equals to the `VALUE_KEY` constant, and the value
332 // is a `Start` event (the value deserializer will see that event)
333 ValueSource::Content => seed.deserialize(MapValueDeserializer {
334 map: self,
335 allow_start: false,
336 }),
337 // This arm processes the following XML shape:
338 // <any-tag>
339 // <tag>...</tag>
340 // </any-tag>
341 // The whole map represented by an `<any-tag>` element, the map key
342 // is a `tag`, and the value is a `Start` event (the value deserializer
343 // will see that event)
344 ValueSource::Nested => seed.deserialize(MapValueDeserializer {
345 map: self,
346 allow_start: true,
347 }),
348 ValueSource::Unknown => Err(DeError::KeyNotRead),
349 }
350 }
351}
352
353////////////////////////////////////////////////////////////////////////////////////////////////////
354
355macro_rules! forward {
356 (
357 $deserialize:ident
358 $(
359 ($($name:ident : $type:ty),*)
360 )?
361 ) => {
362 #[inline]
363 fn $deserialize<V: Visitor<'de>>(
364 self,
365 $($($name: $type,)*)?
366 visitor: V
367 ) -> Result<V::Value, Self::Error> {
368 self.map.de.$deserialize($($($name,)*)? visitor)
369 }
370 };
371}
372
373/// A deserializer for a value of map or struct. That deserializer slightly
374/// differently processes events for a primitive types and sequences than
375/// a [`Deserializer`].
376struct MapValueDeserializer<'de, 'a, 'm, R, E>
377where
378 R: XmlRead<'de>,
379 E: EntityResolver,
380{
381 /// Access to the map that created this deserializer. Gives access to the
382 /// context, such as list of fields, that current map known about.
383 map: &'m mut MapAccess<'de, 'a, R, E>,
384 /// Determines, should [`Deserializer::read_string_impl()`] expand the second
385 /// level of tags or not.
386 ///
387 /// If this field is `true`, we process the following XML shape:
388 ///
389 /// ```xml
390 /// <any-tag>
391 /// <tag>...</tag>
392 /// </any-tag>
393 /// ```
394 ///
395 /// The whole map represented by an `<any-tag>` element, the map key is a `tag`,
396 /// and the value starts with is a `Start("tag")` (the value deserializer will
397 /// see that event first) and extended to the matching `End("tag")` event.
398 /// In order to deserialize primitives (such as `usize`) we need to allow to
399 /// look inside the one levels of tags, so the
400 ///
401 /// ```xml
402 /// <tag>42<tag>
403 /// ```
404 ///
405 /// could be deserialized into `42usize` without problems, and at the same time
406 ///
407 /// ```xml
408 /// <tag>
409 /// <key1/>
410 /// <key2/>
411 /// <!--...-->
412 /// <tag>
413 /// ```
414 /// could be deserialized to a struct.
415 ///
416 /// If this field is `false`, we processes the one of following XML shapes:
417 ///
418 /// ```xml
419 /// <any-tag>
420 /// text value
421 /// </any-tag>
422 /// ```
423 /// ```xml
424 /// <any-tag>
425 /// <![CDATA[cdata value]]>
426 /// </any-tag>
427 /// ```
428 /// ```xml
429 /// <any-tag>
430 /// <any>...</any>
431 /// </any-tag>
432 /// ```
433 ///
434 /// The whole map represented by an `<any-tag>` element, the map key is
435 /// implicit and equals to the [`VALUE_KEY`] constant, and the value is
436 /// a [`Text`], or a [`Start`] event (the value deserializer
437 /// will see one of those events). In the first two cases the value of this
438 /// field do not matter (because we already see the textual event and there
439 /// no reasons to look "inside" something), but in the last case the primitives
440 /// should raise a deserialization error, because that means that you trying
441 /// to deserialize the following struct:
442 ///
443 /// ```ignore
444 /// struct AnyName {
445 /// #[serde(rename = "$text")]
446 /// any_name: String,
447 /// }
448 /// ```
449 /// which means that `any_name` should get a content of the `<any-tag>` element.
450 ///
451 /// Changing this can be valuable for <https://github.com/tafia/quick-xml/issues/383>,
452 /// but those fields should be explicitly marked that they want to get any
453 /// possible markup as a `String` and that mark is different from marking them
454 /// as accepting "text content" which the currently `$text` means.
455 ///
456 /// [`Text`]: DeEvent::Text
457 /// [`Start`]: DeEvent::Start
458 allow_start: bool,
459}
460
461impl<'de, 'a, 'm, R, E> MapValueDeserializer<'de, 'a, 'm, R, E>
462where
463 R: XmlRead<'de>,
464 E: EntityResolver,
465{
466 /// Returns a next string as concatenated content of consequent [`Text`] and
467 /// [`CData`] events, used inside [`deserialize_primitives!()`].
468 ///
469 /// [`Text`]: crate::events::Event::Text
470 /// [`CData`]: crate::events::Event::CData
471 #[inline]
472 fn read_string(&mut self) -> Result<Cow<'de, str>, DeError> {
473 self.map.de.read_string_impl(self.allow_start)
474 }
475}
476
477impl<'de, 'a, 'm, R, E> de::Deserializer<'de> for MapValueDeserializer<'de, 'a, 'm, R, E>
478where
479 R: XmlRead<'de>,
480 E: EntityResolver,
481{
482 type Error = DeError;
483
484 deserialize_primitives!(mut);
485
486 forward!(deserialize_unit);
487
488 forward!(deserialize_map);
489 forward!(deserialize_struct(
490 name: &'static str,
491 fields: &'static [&'static str]
492 ));
493
494 forward!(deserialize_enum(
495 name: &'static str,
496 variants: &'static [&'static str]
497 ));
498
499 forward!(deserialize_any);
500 forward!(deserialize_ignored_any);
501
502 fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, DeError>
503 where
504 V: Visitor<'de>,
505 {
506 deserialize_option!(self.map.de, self, visitor)
507 }
508
509 /// Deserializes each `<tag>` in
510 /// ```xml
511 /// <any-tag>
512 /// <tag>...</tag>
513 /// <tag>...</tag>
514 /// <tag>...</tag>
515 /// </any-tag>
516 /// ```
517 /// as a sequence item, where `<any-tag>` represents a Map in a [`Self::map`],
518 /// and a `<tag>` is a sequential field of that map.
519 fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
520 where
521 V: Visitor<'de>,
522 {
523 let filter = if self.allow_start {
524 match self.map.de.peek()? {
525 // Clone is cheap if event borrows from the input
526 DeEvent::Start(e) => TagFilter::Include(e.clone()),
527 // SAFETY: we use that deserializer with `allow_start == true`
528 // only from the `MapAccess::next_value_seed` and only when we
529 // peeked `Start` event
530 _ => unreachable!(),
531 }
532 } else {
533 TagFilter::Exclude(self.map.fields)
534 };
535 visitor.visit_seq(MapValueSeqAccess {
536 #[cfg(feature = "overlapped-lists")]
537 checkpoint: self.map.de.skip_checkpoint(),
538
539 map: self.map,
540 filter,
541 })
542 }
543
544 #[inline]
545 fn is_human_readable(&self) -> bool {
546 self.map.de.is_human_readable()
547 }
548}
549
550////////////////////////////////////////////////////////////////////////////////////////////////////
551
552/// Check if tag `start` is included in the `fields` list. `decoder` is used to
553/// get a string representation of a tag.
554///
555/// Returns `true`, if `start` is not in the `fields` list and `false` otherwise.
556fn not_in(
557 fields: &'static [&'static str],
558 start: &BytesStart,
559 decoder: Decoder,
560) -> Result<bool, DeError> {
561 let tag: Cow<'_, str> = decoder.decode(bytes:start.name().into_inner())?;
562
563 Ok(fields.iter().all(|&field: &str| field != tag.as_ref()))
564}
565
566/// A filter that determines, what tags should form a sequence.
567///
568/// There are two types of sequences:
569/// - sequence where each element represented by tags with the same name
570/// - sequence where each element can have a different tag
571///
572/// The first variant could represent a collection of structs, the second --
573/// a collection of enum variants.
574///
575/// In the second case we don't know what tag name should be expected as a
576/// sequence element, so we accept any element. Since the sequence are flattened
577/// into maps, we skip elements which have dedicated fields in a struct by using an
578/// `Exclude` filter that filters out elements with names matching field names
579/// from the struct.
580///
581/// # Lifetimes
582///
583/// `'de` represents a lifetime of the XML input, when filter stores the
584/// dedicated tag name
585#[derive(Debug)]
586enum TagFilter<'de> {
587 /// A `SeqAccess` interested only in tags with specified name to deserialize
588 /// an XML like this:
589 ///
590 /// ```xml
591 /// <...>
592 /// <tag/>
593 /// <tag/>
594 /// <tag/>
595 /// ...
596 /// </...>
597 /// ```
598 ///
599 /// The tag name is stored inside (`b"tag"` for that example)
600 Include(BytesStart<'de>), //TODO: Need to store only name instead of a whole tag
601 /// A `SeqAccess` interested in tags with any name, except explicitly listed.
602 /// Excluded tags are used as struct field names and therefore should not
603 /// fall into a `$value` category
604 Exclude(&'static [&'static str]),
605}
606
607impl<'de> TagFilter<'de> {
608 fn is_suitable(&self, start: &BytesStart, decoder: Decoder) -> Result<bool, DeError> {
609 match self {
610 Self::Include(n: &BytesStart<'de>) => Ok(n.name() == start.name()),
611 Self::Exclude(fields: &&'static [&'static str]) => not_in(fields, start, decoder),
612 }
613 }
614}
615
616////////////////////////////////////////////////////////////////////////////////////////////////////
617
618/// An accessor to sequence elements forming a value for struct field.
619/// Technically, this sequence is flattened out into structure and sequence
620/// elements are overlapped with other fields of a structure. Each call to
621/// [`Self::next_element_seed`] consumes a next sub-tree or consequent list
622/// of [`Text`] and [`CData`] events.
623///
624/// ```xml
625/// <>
626/// ...
627/// <item>The is the one item</item>
628/// This is <![CDATA[one another]]> item<!-- even when--> it splitted by comments
629/// <tag>...and that is the third!</tag>
630/// ...
631/// </>
632/// ```
633///
634/// Depending on [`Self::filter`], only some of that possible constructs would be
635/// an element.
636///
637/// [`Text`]: crate::events::Event::Text
638/// [`CData`]: crate::events::Event::CData
639struct MapValueSeqAccess<'de, 'a, 'm, R, E>
640where
641 R: XmlRead<'de>,
642 E: EntityResolver,
643{
644 /// Accessor to a map that creates this accessor and to a deserializer for
645 /// a sequence items.
646 map: &'m mut MapAccess<'de, 'a, R, E>,
647 /// Filter that determines whether a tag is a part of this sequence.
648 ///
649 /// When feature `overlapped-lists` is not activated, iteration will stop
650 /// when found a tag that does not pass this filter.
651 ///
652 /// When feature `overlapped-lists` is activated, all tags, that not pass
653 /// this check, will be skipped.
654 filter: TagFilter<'de>,
655
656 /// Checkpoint after which all skipped events should be returned. All events,
657 /// that was skipped before creating this checkpoint, will still stay buffered
658 /// and will not be returned
659 #[cfg(feature = "overlapped-lists")]
660 checkpoint: usize,
661}
662
663#[cfg(feature = "overlapped-lists")]
664impl<'de, 'a, 'm, R, E> Drop for MapValueSeqAccess<'de, 'a, 'm, R, E>
665where
666 R: XmlRead<'de>,
667 E: EntityResolver,
668{
669 fn drop(&mut self) {
670 self.map.de.start_replay(self.checkpoint);
671 }
672}
673
674impl<'de, 'a, 'm, R, E> SeqAccess<'de> for MapValueSeqAccess<'de, 'a, 'm, R, E>
675where
676 R: XmlRead<'de>,
677 E: EntityResolver,
678{
679 type Error = DeError;
680
681 fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, DeError>
682 where
683 T: DeserializeSeed<'de>,
684 {
685 let decoder = self.map.de.reader.decoder();
686 loop {
687 break match self.map.de.peek()? {
688 // If we see a tag that we not interested, skip it
689 #[cfg(feature = "overlapped-lists")]
690 DeEvent::Start(e) if !self.filter.is_suitable(e, decoder)? => {
691 self.map.de.skip()?;
692 continue;
693 }
694 // Stop iteration when list elements ends
695 #[cfg(not(feature = "overlapped-lists"))]
696 DeEvent::Start(e) if !self.filter.is_suitable(e, decoder)? => Ok(None),
697
698 // Stop iteration after reaching a closing tag
699 DeEvent::End(e) if e.name() == self.map.start.name() => Ok(None),
700 // This is a unmatched closing tag, so the XML is invalid
701 DeEvent::End(e) => Err(DeError::UnexpectedEnd(e.name().as_ref().to_owned())),
702 // We cannot get `Eof` legally, because we always inside of the
703 // opened tag `self.map.start`
704 DeEvent::Eof => Err(DeError::UnexpectedEof),
705
706 // Start(tag), Text
707 _ => seed
708 .deserialize(SeqItemDeserializer { map: self.map })
709 .map(Some),
710 };
711 }
712 }
713}
714
715////////////////////////////////////////////////////////////////////////////////////////////////////
716
717/// A deserializer for a single item of a sequence.
718struct SeqItemDeserializer<'de, 'a, 'm, R, E>
719where
720 R: XmlRead<'de>,
721 E: EntityResolver,
722{
723 /// Access to the map that created this deserializer. Gives access to the
724 /// context, such as list of fields, that current map known about.
725 map: &'m mut MapAccess<'de, 'a, R, E>,
726}
727
728impl<'de, 'a, 'm, R, E> SeqItemDeserializer<'de, 'a, 'm, R, E>
729where
730 R: XmlRead<'de>,
731 E: EntityResolver,
732{
733 /// Returns a next string as concatenated content of consequent [`Text`] and
734 /// [`CData`] events, used inside [`deserialize_primitives!()`].
735 ///
736 /// [`Text`]: crate::events::Event::Text
737 /// [`CData`]: crate::events::Event::CData
738 #[inline]
739 fn read_string(&mut self) -> Result<Cow<'de, str>, DeError> {
740 self.map.de.read_string_impl(allow_start:true)
741 }
742}
743
744impl<'de, 'a, 'm, R, E> de::Deserializer<'de> for SeqItemDeserializer<'de, 'a, 'm, R, E>
745where
746 R: XmlRead<'de>,
747 E: EntityResolver,
748{
749 type Error = DeError;
750
751 deserialize_primitives!(mut);
752
753 forward!(deserialize_unit);
754
755 forward!(deserialize_map);
756 forward!(deserialize_struct(
757 name: &'static str,
758 fields: &'static [&'static str]
759 ));
760
761 forward!(deserialize_enum(
762 name: &'static str,
763 variants: &'static [&'static str]
764 ));
765
766 forward!(deserialize_any);
767 forward!(deserialize_ignored_any);
768
769 fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, DeError>
770 where
771 V: Visitor<'de>,
772 {
773 deserialize_option!(self.map.de, self, visitor)
774 }
775
776 /// This method deserializes a sequence inside of element that itself is a
777 /// sequence element:
778 ///
779 /// ```xml
780 /// <>
781 /// ...
782 /// <self>inner sequence</self>
783 /// <self>inner sequence</self>
784 /// <self>inner sequence</self>
785 /// ...
786 /// </>
787 /// ```
788 fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
789 where
790 V: Visitor<'de>,
791 {
792 match self.map.de.next()? {
793 DeEvent::Text(e) => {
794 SimpleTypeDeserializer::from_text_content(e).deserialize_seq(visitor)
795 }
796 // This is a sequence element. We cannot treat it as another flatten
797 // sequence if type will require `deserialize_seq` We instead forward
798 // it to `xs:simpleType` implementation
799 DeEvent::Start(e) => {
800 let value = match self.map.de.next()? {
801 DeEvent::Text(e) => {
802 SimpleTypeDeserializer::from_text_content(e).deserialize_seq(visitor)
803 }
804 e => Err(DeError::Unsupported(
805 format!("unsupported event {:?}", e).into(),
806 )),
807 };
808 // TODO: May be assert that here we expect only matching closing tag?
809 self.map.de.read_to_end(e.name())?;
810 value
811 }
812 // SAFETY: we use that deserializer only when Start(element) or Text
813 // event was peeked already
814 _ => unreachable!(),
815 }
816 }
817
818 #[inline]
819 fn is_human_readable(&self) -> bool {
820 self.map.de.is_human_readable()
821 }
822}
823
824////////////////////////////////////////////////////////////////////////////////////////////////////
825
826#[test]
827fn test_not_in() {
828 let tag = BytesStart::new("tag");
829
830 assert_eq!(not_in(&[], &tag, Decoder::utf8()).unwrap(), true);
831 assert_eq!(
832 not_in(&["no", "such", "tags"], &tag, Decoder::utf8()).unwrap(),
833 true
834 );
835 assert_eq!(
836 not_in(&["some", "tag", "included"], &tag, Decoder::utf8()).unwrap(),
837 false
838 );
839}
840