use std::io::BufRead;
use crate::XmlVersion;
use crate::de::event::PayloadEvent;
use crate::encoding::Decoder;
use crate::errors::serialize::DeError;
use crate::events::{BytesStart, Event};
use crate::name::QName;
use crate::reader::NsReader;
#[inline(always)]
fn skip_uninterested<'a>(event: Event<'a>) -> Option<PayloadEvent<'a>> {
let event = match event {
Event::DocType(e) => PayloadEvent::DocType(e),
Event::Start(e) => PayloadEvent::Start(e),
Event::End(e) => PayloadEvent::End(e),
Event::Eof => PayloadEvent::Eof,
Event::CData(e) => PayloadEvent::CData(e),
Event::Text(e) => PayloadEvent::Text(e),
Event::GeneralRef(e) => PayloadEvent::GeneralRef(e),
_ => return None,
};
Some(event)
}
pub trait XmlRead<'i> {
fn next(&mut self) -> Result<PayloadEvent<'i>, DeError>;
fn read_to_end(&mut self, name: QName) -> Result<(), DeError>;
fn xml_version(&self) -> XmlVersion;
fn decoder(&self) -> Decoder;
fn has_nil_attr(&self, start: &BytesStart) -> bool;
}
pub struct IoReader<R: BufRead> {
pub(crate) reader: NsReader<R>,
pub(crate) buf: Vec<u8>,
pub(crate) version: XmlVersion,
}
impl<R: BufRead> IoReader<R> {
pub const fn get_ref(&self) -> &NsReader<R> {
&self.reader
}
}
impl<'i, R: BufRead> XmlRead<'i> for IoReader<R> {
fn next(&mut self) -> Result<PayloadEvent<'static>, DeError> {
loop {
self.buf.clear();
let event = self.reader.read_event_into(&mut self.buf)?;
if let Event::Decl(e) = &event {
self.version = e.xml_version()?;
}
if let Some(event) = skip_uninterested(event) {
return Ok(event.into_owned());
}
}
}
fn read_to_end(&mut self, name: QName) -> Result<(), DeError> {
match self.reader.read_to_end_into(name, &mut self.buf) {
Err(e) => Err(e.into()),
Ok(_) => Ok(()),
}
}
#[inline]
fn xml_version(&self) -> XmlVersion {
self.version
}
#[inline]
fn decoder(&self) -> Decoder {
self.reader.decoder()
}
fn has_nil_attr(&self, start: &BytesStart) -> bool {
start.attributes().has_nil(self.reader.resolver())
}
}
pub struct SliceReader<'de> {
pub(crate) reader: NsReader<&'de [u8]>,
pub(crate) version: XmlVersion,
}
impl<'de> SliceReader<'de> {
pub const fn get_ref(&self) -> &NsReader<&'de [u8]> {
&self.reader
}
}
impl<'de> XmlRead<'de> for SliceReader<'de> {
fn next(&mut self) -> Result<PayloadEvent<'de>, DeError> {
loop {
let event = self.reader.read_event()?;
if let Event::Decl(e) = &event {
self.version = e.xml_version()?;
}
if let Some(event) = skip_uninterested(event) {
return Ok(event);
}
}
}
fn read_to_end(&mut self, name: QName) -> Result<(), DeError> {
match self.reader.read_to_end(name) {
Err(e) => Err(e.into()),
Ok(_) => Ok(()),
}
}
#[inline]
fn xml_version(&self) -> XmlVersion {
self.version
}
#[inline]
fn decoder(&self) -> Decoder {
self.reader.decoder()
}
fn has_nil_attr(&self, start: &BytesStart) -> bool {
start.attributes().has_nil(self.reader.resolver())
}
}