diff --git a/Cargo.lock b/Cargo.lock index 215071a..134cdc3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,17 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "async-recursion" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -272,6 +283,7 @@ dependencies = [ name = "peanuts" version = "0.1.0" dependencies = [ + "async-recursion", "circular", "futures", "nom", diff --git a/Cargo.toml b/Cargo.toml index 5586a6e..3cb7177 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +async-recursion = "1.1.1" circular = { version = "0.3.0", path = "../circular" } futures = "0.3.30" nom = "7.1.3" diff --git a/src/element.rs b/src/element.rs index 5b5f048..04f2e5e 100644 --- a/src/element.rs +++ b/src/element.rs @@ -54,6 +54,33 @@ pub struct Element { pub content: Vec, } +pub fn escape_str(s: &str) -> String { + let mut string = String::new(); + for str in s.split_inclusive(|c| c == '<' || c == '&' || c == '>') { + if let Some(str) = str.strip_suffix('<') { + if !str.is_empty() { + string.push_str(str) + } + string.push_str("<"); + } else if let Some(str) = str.strip_suffix('&') { + if !str.is_empty() { + string.push_str(str) + } + string.push_str("&"); + } else if let Some(str) = str.strip_suffix('>') { + if !str.is_empty() { + string.push_str(str) + } + string.push_str(">"); + } else { + if !str.is_empty() { + string.push_str(str) + } + } + } + string +} + // impl<'s> TryFrom> for Element<'s> { // type Error = Error; diff --git a/src/reader.rs b/src/reader.rs index 8387373..f1f3744 100644 --- a/src/reader.rs +++ b/src/reader.rs @@ -48,7 +48,7 @@ where Ok(self.inner.read_buf(&mut self.buffer).await?) } - async fn read_prolog<'s>(&'s mut self) -> Result<()> { + pub async fn read_prolog<'s>(&'s mut self) -> Result<()> { loop { self.read_buf().await?; let input = str::from_utf8(self.buffer.data())?; @@ -68,7 +68,7 @@ where } } - async fn read_start_tag<'s>(&'s mut self) -> Result { + pub async fn read_start_tag<'s>(&'s mut self) -> Result { loop { self.read_buf().await?; let input = str::from_utf8(self.buffer.data())?; @@ -93,7 +93,7 @@ where } } - async fn read_end_tag<'s>(&'s mut self) -> Result<()> { + pub async fn read_end_tag<'s>(&'s mut self) -> Result<()> { loop { self.read_buf().await?; let input = str::from_utf8(self.buffer.data())?; @@ -118,7 +118,7 @@ where } } - async fn read_element<'s>(&'s mut self) -> Result { + pub async fn read_element<'s>(&'s mut self) -> Result { loop { self.read_buf().await?; let input = str::from_utf8(self.buffer.data())?; @@ -140,7 +140,7 @@ where } } - async fn read_content<'s>(&'s mut self) -> Result { + pub async fn read_content<'s>(&'s mut self) -> Result { let mut last_char = false; let mut text = String::new(); loop { @@ -674,19 +674,21 @@ impl Stream for Reader { } #[cfg(test)] -mod test { +pub(crate) mod test { use futures::{sink::Buffer, StreamExt}; use tokio::io::AsyncRead; + use crate::element::Element; + use super::Reader; - struct MockAsyncReader<'s> { + pub struct MockAsyncReader<'s> { put: bool, data: &'s str, } impl<'s> MockAsyncReader<'s> { - fn new(data: &'s str) -> Self { + pub fn new(data: &'s str) -> Self { Self { put: false, data } } } @@ -705,7 +707,7 @@ mod test { } } - const TEST_DOC: &'static str = "