aboutsummaryrefslogtreecommitdiffstats
path: root/src/reader.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/reader.rs')
-rw-r--r--src/reader.rs31
1 files changed, 30 insertions, 1 deletions
diff --git a/src/reader.rs b/src/reader.rs
index 074ab99..24cc098 100644
--- a/src/reader.rs
+++ b/src/reader.rs
@@ -30,6 +30,7 @@ pub struct Reader<R> {
// to have names reference namespaces could
depth: Vec<Name>,
namespace_declarations: Vec<HashSet<NamespaceDeclaration>>,
+ root_ended: bool,
}
impl<R> Reader<R> {
@@ -49,6 +50,7 @@ impl<R> Reader<R> {
depth: Vec::new(),
// TODO: make sure reserved namespaces are never overwritten
namespace_declarations: vec![default_declarations],
+ root_ended: false,
}
}
@@ -66,6 +68,9 @@ where
}
pub async fn read_prolog<'s>(&'s mut self) -> Result<Option<Declaration>> {
+ if self.root_ended {
+ return Err(Error::RootElementEnded);
+ }
loop {
let input = str::from_utf8(self.buffer.data())?;
match xml::Prolog::parse(input) {
@@ -114,6 +119,9 @@ where
}
pub async fn read_start_tag<'s>(&'s mut self) -> Result<Element> {
+ if self.root_ended {
+ return Err(Error::RootElementEnded);
+ }
loop {
let input = str::from_utf8(self.buffer.data())?;
match xml::STag::parse(input) {
@@ -140,6 +148,9 @@ where
}
pub async fn read_end_tag<'s>(&'s mut self) -> Result<()> {
+ if self.root_ended {
+ return Err(Error::RootElementEnded);
+ }
loop {
let input = str::from_utf8(self.buffer.data())?;
match xml::ETag::parse(input) {
@@ -150,6 +161,9 @@ where
&mut self.namespace_declarations,
e,
)?;
+ if self.depth.is_empty() {
+ self.root_ended = true
+ }
self.buffer.consume(len);
return Ok(());
}
@@ -166,6 +180,9 @@ where
}
pub async fn read_element<'s>(&'s mut self) -> Result<Element> {
+ if self.root_ended {
+ return Err(Error::RootElementEnded);
+ }
loop {
let input = str::from_utf8(self.buffer.data())?;
match xml::Element::parse(input) {
@@ -173,6 +190,9 @@ where
let len = self.buffer.available_data() - rest.as_bytes().len();
let element =
Reader::<R>::element_from_xml(&mut self.namespace_declarations, e)?;
+ if self.depth.is_empty() {
+ self.root_ended = true
+ }
self.buffer.consume(len);
return Ok(element);
}
@@ -189,6 +209,9 @@ where
}
pub async fn read_content<'s>(&'s mut self) -> Result<Content> {
+ if self.root_ended {
+ return Err(Error::RootElementEnded);
+ }
let mut last_char = false;
let mut text = String::new();
loop {
@@ -217,6 +240,9 @@ where
&mut self.namespace_declarations,
element,
)?;
+ if self.depth.is_empty() {
+ self.root_ended = true
+ }
self.buffer.consume(len);
return Ok(Content::Element(element));
}
@@ -279,6 +305,9 @@ where
&mut self.namespace_declarations,
element,
)?;
+ if self.depth.is_empty() {
+ self.root_ended = true
+ }
self.buffer.consume(len);
return Ok(Content::Element(element));
}
@@ -722,7 +751,7 @@ impl<R> Reader<R> {
}
#[cfg(test)]
-pub(crate) mod test {
+pub mod test {
use tokio::io::AsyncRead;
use super::Reader;