// use quick_xml::events::BytesDecl; pub mod bind; pub mod iq; pub mod sasl; pub mod stream; use std::collections::BTreeMap; use std::str; // const DECLARATION: BytesDecl<'_> = BytesDecl::new("1.0", None, None); use async_recursion::async_recursion; use quick_xml::events::{BytesEnd, BytesStart, BytesText, Event}; use quick_xml::{Reader, Writer}; use tokio::io::{AsyncBufRead, AsyncWrite}; use crate::{JabberError, Result}; // #[derive(Clone, Debug)] // pub struct EventTree<'e> { // pub event: Event<'e>, // pub children: Option>>, // } pub type Prefix<'s> = Option<&'s str>; #[derive(Clone, Debug)] /// represents an xml element as a tree of nodes pub struct Element<'s> { /// element prefix /// e.g. `foo` in ``. prefix: Option<&'s str>, /// element name /// e.g. `bar` in ``. localname: &'s str, /// qualifying namespace /// an element must be qualified by a namespace /// e.g. for `` in /// ``` /// /// /// /// /// zlib /// lzw /// /// /// /// ``` /// would be `"http://etherx.jabber.org/streams"` but for /// ``` /// /// /// /// /// zlib /// lzw /// /// /// /// ``` /// would be `"jabber:client"` namespace: &'s str, /// all namespaces applied to element /// e.g. for `` in /// ``` /// /// /// /// zlib /// lzw /// /// /// ``` /// would be `[(None, "urn:ietf:params:xml:ns:xmpp-bind")]` despite /// `(Some("stream"), "http://etherx.jabber.org/streams")` also being available namespace_declarations: Box, &'s str>>, /// element attributes attributes: Box>, // children elements namespaces contain their parents' namespaces children: Box>>, } #[derive(Clone, Debug)] pub enum Node<'s> { Element(Element<'s>), Text(&'s str), } impl<'s> From<&Node<'s>> for Vec> { fn from(node: &Node<'s>) -> Self { match node { Node::Element(e) => e.into(), Node::Text(t) => vec![Event::Text(BytesText::new(t))], } } } impl<'s> Element<'s> { /// returns the fully qualified name /// e.g. `foo:bar` in /// ``. pub fn name(&self) -> &str { if let Some(prefix) = self.prefix { format!("{}:{}", prefix, self.localname).as_str() } else { self.localname } } /// returns the localname. /// e.g. `bar` in `` pub fn localname(&self) -> &str { self.localname } /// returns the prefix. /// e.g. `foo` in ``. returns None if there is /// no prefix. pub fn prefix(&self) -> Option<&str> { self.prefix } /// returns the namespace which applies to the current element, e.g. for /// `` /// it will be `foo` but for /// `` /// it will be `bar`. pub fn namespace(&self) -> &str { self.namespace } } impl<'s> From<&Element<'s>> for Vec> { fn from(element: &Element<'s>) -> Self { let name = element.name(); let event = BytesStart::new(name); // namespace declarations let namespace_declarations = element.namespace_declarations.iter().map(|declaration| { let (prefix, namespace) = declaration; match prefix { Some(prefix) => return (format!("xmlns:{}", prefix).as_str(), *namespace), None => return ("xmlns", *namespace), } }); let event = event.with_attributes(namespace_declarations); // attributes let event = event.with_attributes(element.attributes.into_iter()); match element.children.is_empty() { true => return vec![Event::Empty(event)], false => { return { let start: Vec> = vec![Event::Start(event)]; let start_and_content: Vec> = start .into_iter() .chain({ let u = element.children.iter().fold( Vec::new(), |acc: Vec>, child: &Node<'s>| { acc.into_iter() .chain(Into::>>::into(child).into_iter()) .collect() }, ); u }) .collect(); let full: Vec> = start_and_content .into_iter() .chain(vec![Event::End(BytesEnd::new(name))]) .collect(); full } } } } } impl<'s> Element<'s> { /// if there is only one child in the vec of children, will return that element pub fn child(&self) -> Result<&Element<'s>> { if self.children.len() == 1 { Ok(&self.children[0]) } else { Err(ElementError::NoChildren.into()) } } /// returns reference to children pub fn children(&self) -> Result<&Vec>> { if !self.children.is_empty() { Ok(&self.children) } else { Err(ElementError::NoChildren.into()) } } /// returns text content, error if there is none pub fn content(&self) -> Result<&str> { for node in *self.children { match node { Node::Text(t) => return Ok(t), _ => {} } } Err(ElementError::NotText) } pub async fn write(&self, writer: &mut Writer) -> Result<()> { let events: Vec = self.into(); for event in events { writer.write_event_async(event).await? } Ok(()) } pub async fn write_start( &self, writer: &mut Writer, ) -> Result<()> { let mut event = BytesStart::new(self.name()); // namespace declarations self.namespace_declarations.iter().for_each(|declaration| { let (prefix, namespace) = declaration; match prefix { Some(prefix) => { event.push_attribute((format!("xmlns:{}", prefix).as_str(), *namespace)) } None => event.push_attribute(("xmlns", *namespace)), } }); // attributes let event = event.with_attributes(self.attributes.iter().map(|(attr, value)| (*attr, *value))); writer.write_event_async(Event::Start(event)).await?; Ok(()) } pub async fn write_end( &self, writer: &mut Writer, ) -> Result<()> { let event = BytesEnd::new(self.name()); writer.write_event_async(Event::End(event)).await?; Ok(()) } // pub async fn write_start( // &self, // writer: &mut Writer, // ) -> Result<(), JabberError> { // 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( // &self, // writer: &mut Writer, // ) -> Result<(), JabberError> { // 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( reader: &mut Reader, local_namespaces: BTreeMap, &str>, ) -> Result { let node = Node::read_recursive(reader, local_namespaces) .await? .ok_or(JabberError::UnexpectedEnd)?; match node { Node::Element(e) => Ok(e), Node::Text(_) => Err(JabberError::UnexpectedText), } } } impl<'s> Node<'s> { #[async_recursion] async fn read_recursive( reader: &mut Reader, local_namespaces: BTreeMap, &str>, ) -> Result>> { let mut buf = Vec::new(); let event = reader.read_event_into_async(&mut buf).await?; match event { Event::Start(e) => { let prefix = e .name() .prefix() .map(|prefix| str::from_utf8(prefix.into_inner())?); let mut children_vec: Vec = Vec::new(); while let Some(sub_element) = Element::read_recursive(reader).await? { children_vec.push(sub_element) } Ok(Some(Self::Element(Element { prefix, localname: e.local_name().into_inner(), namespace: todo!(), namespace_declarations: todo!(), attributes: todo!(), children: todo!(), }))) } Event::End(_) => Ok(None), Event::Text(e) => Ok(Some(Self::Text(e.unescape()?.as_ref()))), e => Ok(Some(Self { event: e.into_owned(), children: None, })), } } } // #[async_recursion] // pub async fn read_start( // reader: &mut Reader, // ) -> Result { // 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()), // children: None, // }) // } // e => Err(ElementError::NotAStart(e.into_owned()).into()), // } // } // pub trait IntoElement<'e> { // fn event(&self) -> Event<'e>; // fn children(&self) -> Option>>; // } // impl<'e, T: IntoElement<'e>> From for Element<'e> { // fn from(value: T) -> Self { // Element { // event: value.event(), // children: value.children(), // } // } // } #[derive(Debug)] pub enum ElementError<'e> { NotAStart(Event<'e>), NotText, NoChildren, MultipleChildren, }