use xsd_parser_types::quick_xml::{Error, Event, XmlReader, XmlReaderSync};
pub(crate) struct RootRecordingReader<R> {
inner: R,
root: Option<Vec<u8>>,
}
impl<R> RootRecordingReader<R> {
pub(crate) fn new(inner: R) -> Self {
Self { inner, root: None }
}
pub(crate) fn root_name(&self) -> Option<&[u8]> {
self.root.as_deref()
}
}
impl<R: XmlReader> XmlReader for RootRecordingReader<R> {
fn extend_error(&self, error: Error) -> Error {
self.inner.extend_error(error)
}
}
impl<'a, R: XmlReaderSync<'a>> XmlReaderSync<'a> for RootRecordingReader<R> {
fn read_event(&mut self) -> Result<Event<'a>, Error> {
let event = self.inner.read_event()?;
if self.root.is_none() {
if let Event::Start(start) | Event::Empty(start) = &event {
self.root = Some(start.local_name().as_ref().to_vec());
}
}
Ok(event)
}
}
pub(crate) fn ensure_root_is<R>(
reader: &RootRecordingReader<R>,
expected: &str,
what: &str,
) -> anyhow::Result<()> {
match reader.root_name() {
Some(name) if name == expected.as_bytes() => Ok(()),
Some(name) => anyhow::bail!(
"not a {what}: expected a <{expected}> root element, found <{}>",
String::from_utf8_lossy(name)
),
None => anyhow::bail!("not a {what}: the document has no root element"),
}
}