mod error_reader;
mod io_reader;
mod slice_reader;
#[cfg(feature = "async")]
mod fut;
#[cfg(feature = "async")]
use std::future::Future;
use quick_xml::{
events::Event,
name::{LocalName, PrefixIter, QName, ResolveResult},
};
pub use self::error_reader::ErrorReader;
pub use self::io_reader::IoReader;
pub use self::slice_reader::SliceReader;
#[cfg(feature = "async")]
pub use self::fut::{ReadTag, SkipCurrent};
use super::{Error, ErrorKind};
pub trait XmlReader: Sized {
fn resolve<'n>(&self, name: QName<'n>, attribute: bool) -> (ResolveResult<'_>, LocalName<'n>);
fn prefixes(&self) -> PrefixIter<'_>;
fn current_position(&self) -> u64;
fn error_position(&self) -> u64;
fn extend_error(&self, error: Error) -> Error {
error.with_pos(self.error_position())
}
fn map_error<E>(&self, error: E) -> Error
where
Error: From<E>,
{
self.extend_error(Error::from(error))
}
#[allow(clippy::missing_errors_doc)]
fn map_result<T, E>(&self, result: Result<T, E>) -> Result<T, Error>
where
Error: From<E>,
{
result.map_err(|error| self.map_error(error))
}
#[allow(clippy::missing_errors_doc)]
fn err<E>(&self, error: E) -> Result<(), Error>
where
Error: From<E>,
{
Err(self.map_error(error))
}
fn with_error_info(self) -> ErrorReader<Self> {
ErrorReader::new(self)
}
}
pub trait XmlReaderSync<'a>: XmlReader {
fn read_event(&mut self) -> Result<Event<'a>, Error>;
fn read_tag(&mut self) -> Result<Event<'a>, Error> {
loop {
if let e @ (Event::Start(_) | Event::Empty(_) | Event::End(_)) = self.read_event()? {
break Ok(e);
}
}
}
fn skip_current(&mut self) -> Result<(), Error> {
let mut depth = 0usize;
loop {
let event = self.read_event()?;
match event {
Event::Start(_) => depth += 1,
Event::End(_) if depth == 1 => return Ok(()),
Event::End(_) => depth -= 1,
Event::Eof => Err(ErrorKind::UnexpectedEof)?,
_ if depth > 0 => (),
_ => return Ok(()),
}
}
}
}
#[cfg(feature = "async")]
pub trait XmlReaderAsync<'a>: XmlReader {
type ReadEventFut<'x>: Future<Output = Result<Event<'a>, Error>> + Unpin
where
Self: 'x;
fn read_event_async(&mut self) -> Self::ReadEventFut<'_>;
fn read_tag_async(&mut self) -> ReadTag<'a, '_, Self> {
ReadTag::new(self)
}
fn skip_current_async(&mut self) -> SkipCurrent<'a, '_, Self> {
SkipCurrent::new(self)
}
}