From c1e6f7e918eacaad9c8b1a4b27fcd4d6245aaf68 Mon Sep 17 00:00:00 2001 From: cel 🌸 Date: Wed, 20 Nov 2024 16:43:34 +0000 Subject: implement element writing --- src/element.rs | 27 ++++++++++ src/reader.rs | 20 ++++---- src/writer.rs | 160 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- src/xml/mod.rs | 2 +- 4 files changed, 188 insertions(+), 21 deletions(-) (limited to 'src') 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 = "