diff options
| author | 2023-07-12 12:41:36 +0100 | |
|---|---|---|
| committer | 2023-07-12 12:41:36 +0100 | |
| commit | ae00389cb74919a93de9d67c996bebed4f241cbb (patch) | |
| tree | 6dbca9aae5bb6943c112ae6ac567c753cf131e2d /src/stanza | |
| parent | f43911ccbae3856b35b0d3e8ec6ac6450e295da6 (diff) | |
| download | luz-ae00389cb74919a93de9d67c996bebed4f241cbb.tar.gz luz-ae00389cb74919a93de9d67c996bebed4f241cbb.tar.bz2 luz-ae00389cb74919a93de9d67c996bebed4f241cbb.zip | |
move Element to stanza and make write() a method
Diffstat (limited to 'src/stanza')
| -rw-r--r-- | src/stanza/mod.rs | 120 | ||||
| -rw-r--r-- | src/stanza/stream.rs | 3 | 
2 files changed, 122 insertions, 1 deletions
| diff --git a/src/stanza/mod.rs b/src/stanza/mod.rs index 02ea277..16f3bdd 100644 --- a/src/stanza/mod.rs +++ b/src/stanza/mod.rs @@ -4,3 +4,123 @@ pub mod sasl;  pub mod stream;  // const DECLARATION: BytesDecl<'_> = BytesDecl::new("1.0", None, None); +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>>>, +} + +impl<'e: 'async_recursion, 'async_recursion> Element<'e> { +    pub fn write<'life0, W: AsyncWrite + Unpin + Send>( +        &'async_recursion self, +        writer: &'life0 mut Writer<W>, +    ) -> ::core::pin::Pin< +        Box< +            dyn ::core::future::Future<Output = Result<()>> +                + 'async_recursion +                + ::core::marker::Send, +        >, +    > +    where +        W: 'async_recursion, +        'life0: 'async_recursion, +    { +        Box::pin(async move { +            match &self.event { +                Event::Start(e) => { +                    writer.write_event_async(Event::Start(e.clone())).await?; +                    if let Some(content) = &self.content { +                        for _e in content { +                            self.write(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>), +} diff --git a/src/stanza/stream.rs b/src/stanza/stream.rs index f0fb6a1..59d0b90 100644 --- a/src/stanza/stream.rs +++ b/src/stanza/stream.rs @@ -5,7 +5,8 @@ use quick_xml::{      name::QName,  }; -use crate::{element::Element, JabberError, Result, JID}; +use super::Element; +use crate::{JabberError, Result, JID};  const XMLNS_STREAM: &str = "http://etherx.jabber.org/streams";  const VERSION: &str = "1.0"; | 
