serde_xml_rs/de/
seq.rs
1use std::io::Read;
2
3use serde::de;
4use xml::reader::XmlEvent;
5
6use crate::de::ChildDeserializer;
7use crate::debug_expect;
8use crate::error::{Error, Result};
9
10pub struct SeqAccess<'a, R: Read> {
11 de: ChildDeserializer<'a, R>,
12 max_size: Option<usize>,
13 seq_type: SeqType,
14}
15
16pub enum SeqType {
17 ByElementName {
19 expected_name: String,
20 search_non_contiguous: bool,
21 },
22 AllMembers,
24}
25
26impl<'a, R: 'a + Read> SeqAccess<'a, R> {
27 pub fn new(mut de: ChildDeserializer<'a, R>, max_size: Option<usize>) -> Self {
28 let seq_type = if de.unset_map_value() {
29 debug_expect!(de.peek(), Ok(&XmlEvent::StartElement { ref name, .. }) => {
30 SeqType::ByElementName {
31 expected_name: name.local_name.clone(),
32 search_non_contiguous: de.non_contiguous_seq_elements
33 }
34 })
35 } else {
36 SeqType::AllMembers
37 };
38 SeqAccess {
39 de,
40 max_size,
41 seq_type,
42 }
43 }
44}
45
46impl<'de, 'a, R: 'a + Read> de::SeqAccess<'de> for SeqAccess<'a, R> {
47 type Error = Error;
48
49 fn next_element_seed<T: de::DeserializeSeed<'de>>(
50 &mut self,
51 seed: T,
52 ) -> Result<Option<T::Value>> {
53 match self.max_size.as_mut() {
54 Some(&mut 0) => {
55 return Ok(None);
56 }
57 Some(max_size) => {
58 *max_size -= 1;
59 }
60 None => {}
61 }
62
63 match &self.seq_type {
64 SeqType::ByElementName {
65 expected_name,
66 search_non_contiguous,
67 } => {
68 let mut local_depth = 0;
69
70 loop {
71 let next_element = self.de.peek()?;
72
73 match next_element {
74 XmlEvent::StartElement { name, .. }
75 if &name.local_name == expected_name && local_depth == 0 =>
76 {
77 self.de.set_map_value();
78 return seed.deserialize(&mut self.de).map(Some);
79 }
80 XmlEvent::StartElement { .. } => {
81 if *search_non_contiguous {
82 self.de.buffered_reader.skip();
83 local_depth += 1;
84 } else {
85 return Ok(None);
86 }
87 }
88 XmlEvent::EndElement { .. } => {
89 if local_depth == 0 {
90 return Ok(None);
91 } else {
92 local_depth -= 1;
93 self.de.buffered_reader.skip();
94 }
95 }
96 XmlEvent::EndDocument => {
97 return Ok(None);
98 }
99 _ => {
100 self.de.buffered_reader.skip();
101 }
102 }
103 }
104 }
105 SeqType::AllMembers => {
106 let next_element = self.de.peek()?;
107
108 match next_element {
109 XmlEvent::EndElement { .. } | XmlEvent::EndDocument => return Ok(None),
110 _ => {
111 return seed.deserialize(&mut self.de).map(Some);
112 }
113 }
114 }
115 }
116 }
117
118 fn size_hint(&self) -> Option<usize> {
119 self.max_size
120 }
121}