move Element to stanza and make write() a method

This commit is contained in:
cel 🌸 2023-07-12 12:41:36 +01:00
parent f43911ccba
commit ae00389cb7
Signed by: cel
GPG Key ID: 48E29AF13B5F1349
6 changed files with 127 additions and 116 deletions

View File

@ -6,8 +6,8 @@ use tokio::io::{BufReader, ReadHalf, WriteHalf};
use tokio::net::TcpStream;
use tokio_native_tls::TlsStream;
use crate::element::Element;
use crate::stanza::stream::{Stream, StreamFeature};
use crate::stanza::Element;
use crate::Jabber;
use crate::Result;

View File

@ -1,5 +1,3 @@
use std::str;
use quick_xml::{
events::{BytesDecl, BytesStart, Event},
name::QName,
@ -9,8 +7,8 @@ use tokio::io::{BufReader, ReadHalf, WriteHalf};
use tokio::net::TcpStream;
use tokio_native_tls::native_tls::TlsConnector;
use crate::element::Element;
use crate::stanza::stream::StreamFeature;
use crate::stanza::Element;
use crate::Jabber;
use crate::Result;
use crate::{error::JabberError, stanza::stream::Stream};

View File

@ -1,108 +0,0 @@
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>),
}

View File

@ -4,8 +4,8 @@ use quick_xml::events::attributes::AttrError;
use rsasl::mechname::MechanismNameError;
use crate::{
element::{self, ElementError},
jid::ParseError,
stanza::{self, ElementError},
};
#[derive(Debug)]
@ -54,8 +54,8 @@ impl From<quick_xml::Error> for JabberError {
}
}
impl From<element::ElementError<'static>> for JabberError {
fn from(e: element::ElementError<'static>) -> Self {
impl From<stanza::ElementError<'static>> for JabberError {
fn from(e: stanza::ElementError<'static>) -> Self {
Self::Element(e)
}
}

View File

@ -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>),
}

View File

@ -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";