diff options
author | cel 🌸 <cel@blos.sm> | 2023-07-11 21:28:42 +0100 |
---|---|---|
committer | cel 🌸 <cel@blos.sm> | 2023-07-11 21:28:42 +0100 |
commit | f43911ccbae3856b35b0d3e8ec6ac6450e295da6 (patch) | |
tree | 492b195cc06b08e546c059c16a748f369995eab1 /src/element.rs | |
parent | 143a0365d0822e6786cdac3530a725bbf450f38f (diff) | |
download | luz-f43911ccbae3856b35b0d3e8ec6ac6450e295da6.tar.gz luz-f43911ccbae3856b35b0d3e8ec6ac6450e295da6.tar.bz2 luz-f43911ccbae3856b35b0d3e8ec6ac6450e295da6.zip |
remove serde functions
Diffstat (limited to 'src/element.rs')
-rw-r--r-- | src/element.rs | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/src/element.rs b/src/element.rs new file mode 100644 index 0000000..21b1a3e --- /dev/null +++ b/src/element.rs @@ -0,0 +1,108 @@ +use async_recursion::async_recursion; +use quick_xml::events::Event; +use quick_xml::{Reader, Writer}; +use tokio::io::{AsyncBufRead, AsyncWrite}; + +use crate::Result; + +#[derive(Debug)] +pub struct Element<'e> { + pub event: Event<'e>, + pub content: Option<Vec<Element<'e>>>, +} + +// TODO: make method +#[async_recursion] +pub async fn write<'e: 'async_recursion, W: AsyncWrite + Unpin + Send>( + element: Element<'e>, + writer: &mut Writer<W>, +) -> Result<()> { + match element.event { + Event::Start(e) => { + writer.write_event_async(Event::Start(e.clone())).await?; + if let Some(content) = element.content { + for e in content { + write(e, writer).await?; + } + } + writer.write_event_async(Event::End(e.to_end())).await?; + return Ok(()); + } + e => Ok(writer.write_event_async(e).await?), + } +} + +impl<'e> Element<'e> { + pub async fn write_start<W: AsyncWrite + Unpin + Send>( + &self, + writer: &mut Writer<W>, + ) -> Result<()> { + match self.event.as_ref() { + Event::Start(e) => Ok(writer.write_event_async(Event::Start(e.clone())).await?), + e => Err(ElementError::NotAStart(e.clone().into_owned()).into()), + } + } + + pub async fn write_end<W: AsyncWrite + Unpin + Send>( + &self, + writer: &mut Writer<W>, + ) -> Result<()> { + match self.event.as_ref() { + Event::Start(e) => Ok(writer + .write_event_async(Event::End(e.clone().to_end())) + .await?), + e => Err(ElementError::NotAStart(e.clone().into_owned()).into()), + } + } + + #[async_recursion] + pub async fn read<R: AsyncBufRead + Unpin + Send>( + reader: &mut Reader<R>, + ) -> Result<Option<Self>> { + let mut buf = Vec::new(); + let event = reader.read_event_into_async(&mut buf).await?; + match event { + Event::Start(e) => { + let mut content_vec = Vec::new(); + while let Some(sub_element) = Element::read(reader).await? { + content_vec.push(sub_element) + } + let mut content = None; + if !content_vec.is_empty() { + content = Some(content_vec) + } + Ok(Some(Self { + event: Event::Start(e.into_owned()), + content, + })) + } + Event::End(_) => Ok(None), + e => Ok(Some(Self { + event: e.into_owned(), + content: None, + })), + } + } + + #[async_recursion] + pub async fn read_start<R: AsyncBufRead + Unpin + Send>( + reader: &mut Reader<R>, + ) -> Result<Self> { + let mut buf = Vec::new(); + let event = reader.read_event_into_async(&mut buf).await?; + match event { + Event::Start(e) => { + return Ok(Self { + event: Event::Start(e.into_owned()), + content: None, + }) + } + e => Err(ElementError::NotAStart(e.into_owned()).into()), + } + } +} + +#[derive(Debug)] +pub enum ElementError<'e> { + NotAStart(Event<'e>), +} |