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    /// Sequence is of elements with the same name.
18    ByElementName {
19        expected_name: String,
20        search_non_contiguous: bool,
21    },
22    /// Sequence is of all elements/text at current depth.
23    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}