1use std::io::Read;
7use std::iter::FusedIterator;
8use std::result;
9
10use crate::common::{Position, TextPosition};
11
12pub use config::ParserConfig;
13pub use error::{Error, ErrorKind, ImmutableEntitiesError};
14pub use events::{DoctypeRef, XmlEvent};
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 lexer;
27mod parser;
28
29pub type Result<T, E = Error> = result::Result<T, E>;
31
32pub struct EventReader<R: Read> {
36 source: R,
37 parser: PullParser,
38}
39
40impl<R: Read> EventReader<R> {
41 #[inline]
43 pub fn new(source: R) -> Self {
44 Self::new_with_config(source, ParserConfig::new())
45 }
46
47 #[inline]
49 pub fn new_with_config(source: R, config: impl Into<ParserConfig>) -> Self {
50 Self {
51 source,
52 parser: PullParser::new(config),
53 }
54 }
55
56 #[inline]
61 #[allow(clippy::should_implement_trait)]
62 pub fn next(&mut self) -> Result<XmlEvent> {
63 self.parser.next(&mut self.source)
64 }
65
66 #[inline]
72 pub fn skip(&mut self) -> Result<()> {
73 let mut depth = 1;
74
75 while depth > 0 {
76 match self.next()? {
77 XmlEvent::StartElement { .. } => depth += 1,
78 XmlEvent::EndElement { .. } => depth -= 1,
79 XmlEvent::EndDocument => return Err(Error {
80 kind: ErrorKind::UnexpectedEof,
81 pos: self.parser.position(),
82 }),
83 _ => {},
84 }
85 }
86
87 Ok(())
88 }
89
90 pub fn source(&self) -> &R { &self.source }
94
95 pub fn source_mut(&mut self) -> &mut R { &mut self.source }
99
100 pub fn into_inner(self) -> R {
106 self.source
107 }
108
109 #[inline]
113 #[deprecated(note = "there is `XmlEvent::Doctype` now")]
114 #[allow(deprecated)]
115 pub fn doctype(&self) -> Option<&str> {
116 self.parser.doctype()
117 }
118
119 #[inline]
123 pub fn doctype_ids(&self) -> Option<DoctypeRef<'_>> {
124 self.parser.doctype_ids()
125 }
126
127 #[inline]
135 pub fn add_entities<S: Into<String>, T: Into<String>>(&mut self, entities: impl IntoIterator<Item=(S, T)>) -> result::Result<(), ImmutableEntitiesError> {
136 self.parser.add_entities(entities)
137 }
138}
139
140impl<B: Read> Position for EventReader<B> {
141 #[inline]
143 fn position(&self) -> TextPosition {
144 self.parser.position()
145 }
146}
147
148impl<R: Read> IntoIterator for EventReader<R> {
149 type IntoIter = Events<R>;
150 type Item = Result<XmlEvent>;
151
152 fn into_iter(self) -> Events<R> {
153 Events { reader: self, finished: false }
154 }
155}
156
157impl<R: Read + Clone> Clone for EventReader<R> {
158 fn clone(&self) -> Self {
159 Self {
160 source: self.source.clone(),
161 parser: self.parser.clone()
162 }
163 }
164}
165
166pub struct Events<R: Read> {
171 reader: EventReader<R>,
172 finished: bool,
173}
174
175impl<R: Read> Events<R> {
176 #[inline]
178 pub fn into_inner(self) -> EventReader<R> {
179 self.reader
180 }
181
182 pub fn source(&self) -> &R { &self.reader.source }
186
187 pub fn source_mut(&mut self) -> &mut R { &mut self.reader.source }
191}
192
193impl<R: Read> std::ops::Deref for Events<R> {
194 type Target = EventReader<R>;
195
196 fn deref(&self) -> &Self::Target {
197 &self.reader
198 }
199}
200
201impl<R: Read> std::ops::DerefMut for Events<R> {
202 fn deref_mut(&mut self) -> &mut Self::Target {
203 &mut self.reader
204 }
205}
206
207impl<R: Read> FusedIterator for Events<R> {
208}
209
210impl<R: Read> Iterator for Events<R> {
211 type Item = Result<XmlEvent>;
212
213 #[inline]
214 fn next(&mut self) -> Option<Result<XmlEvent>> {
215 if self.finished && !self.reader.parser.is_ignoring_end_of_stream() {
216 None
217 } else {
218 let ev = self.reader.next();
219 if let Ok(XmlEvent::EndDocument) | Err(_) = ev {
220 self.finished = true;
221 }
222 Some(ev)
223 }
224 }
225}
226
227impl<'r> EventReader<&'r [u8]> {
228 #[inline]
230 #[must_use]
231 #[allow(clippy::should_implement_trait)]
232 pub fn from_str(source: &'r str) -> Self {
233 EventReader::new(source.as_bytes())
234 }
235}