1use std::io::Read;
7use std::iter::FusedIterator;
8use std::result;
9
10use crate::common::{Position, TextPosition};
11
12pub use self::config::ParserConfig;
13pub use self::error::{Error, ErrorKind};
14pub use events::{XmlEvent, DoctypeRef};
15
16#[doc(hidden)]
18#[deprecated(note = "Merged into ParserConfig")]
19pub type ParserConfig2 = ParserConfig;
20
21use self::parser::PullParser;
22
23mod config;
24mod error;
25mod events;
26mod indexset;
27mod lexer;
28mod parser;
29
30pub type Result<T, E = Error> = result::Result<T, E>;
32
33pub struct EventReader<R: Read> {
37 source: R,
38 parser: PullParser,
39}
40
41impl<R: Read> EventReader<R> {
42 #[inline]
44 pub fn new(source: R) -> Self {
45 Self::new_with_config(source, ParserConfig::new())
46 }
47
48 #[inline]
50 pub fn new_with_config(source: R, config: impl Into<ParserConfig>) -> Self {
51 Self {
52 source,
53 parser: PullParser::new(config),
54 }
55 }
56
57 #[inline]
62 #[allow(clippy::should_implement_trait)]
63 pub fn next(&mut self) -> Result<XmlEvent> {
64 self.parser.next(&mut self.source)
65 }
66
67 #[inline]
73 pub fn skip(&mut self) -> Result<()> {
74 let mut depth = 1;
75
76 while depth > 0 {
77 match self.next()? {
78 XmlEvent::StartElement { .. } => depth += 1,
79 XmlEvent::EndElement { .. } => depth -= 1,
80 XmlEvent::EndDocument => return Err(Error {
81 kind: ErrorKind::UnexpectedEof,
82 pos: self.parser.position(),
83 }),
84 _ => {},
85 }
86 }
87
88 Ok(())
89 }
90
91 pub fn source(&self) -> &R { &self.source }
95
96 pub fn source_mut(&mut self) -> &mut R { &mut self.source }
100
101 pub fn into_inner(self) -> R {
107 self.source
108 }
109
110 #[inline]
114 #[deprecated(note = "there is `XmlEvent::Doctype` now")]
115 #[allow(deprecated)]
116 pub fn doctype(&self) -> Option<&str> {
117 self.parser.doctype()
118 }
119
120 #[inline]
124 pub fn doctype_ids(&self) -> Option<DoctypeRef<'_>> {
125 self.parser.doctype_ids()
126 }
127
128 #[inline]
136 pub fn add_entities<S: Into<String>, T: Into<String>>(&mut self, entities: impl IntoIterator<Item=(S, T)>) -> std::result::Result<(), crate::reader::error::ImmutableEntitiesError> {
137 self.parser.add_entities(entities)
138 }
139}
140
141impl<B: Read> Position for EventReader<B> {
142 #[inline]
144 fn position(&self) -> TextPosition {
145 self.parser.position()
146 }
147}
148
149impl<R: Read> IntoIterator for EventReader<R> {
150 type IntoIter = Events<R>;
151 type Item = Result<XmlEvent>;
152
153 fn into_iter(self) -> Events<R> {
154 Events { reader: self, finished: false }
155 }
156}
157
158pub struct Events<R: Read> {
163 reader: EventReader<R>,
164 finished: bool,
165}
166
167impl<R: Read> Events<R> {
168 #[inline]
170 pub fn into_inner(self) -> EventReader<R> {
171 self.reader
172 }
173
174 pub fn source(&self) -> &R { &self.reader.source }
178
179 pub fn source_mut(&mut self) -> &mut R { &mut self.reader.source }
183}
184
185impl<R: Read> std::ops::Deref for Events<R> {
186 type Target = EventReader<R>;
187
188 fn deref(&self) -> &Self::Target {
189 &self.reader
190 }
191}
192
193impl<R: Read> std::ops::DerefMut for Events<R> {
194 fn deref_mut(&mut self) -> &mut Self::Target {
195 &mut self.reader
196 }
197}
198
199impl<R: Read> FusedIterator for Events<R> {
200}
201
202impl<R: Read> Iterator for Events<R> {
203 type Item = Result<XmlEvent>;
204
205 #[inline]
206 fn next(&mut self) -> Option<Result<XmlEvent>> {
207 if self.finished && !self.reader.parser.is_ignoring_end_of_stream() {
208 None
209 } else {
210 let ev = self.reader.next();
211 if let Ok(XmlEvent::EndDocument) | Err(_) = ev {
212 self.finished = true;
213 }
214 Some(ev)
215 }
216 }
217}
218
219impl<'r> EventReader<&'r [u8]> {
220 #[inline]
222 #[must_use]
223 #[allow(clippy::should_implement_trait)]
224 pub fn from_str(source: &'r str) -> Self {
225 EventReader::new(source.as_bytes())
226 }
227}