// 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::name::PrefixDeclaration; 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), Unknown, } 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))], Unknown => vec![], } } } 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<&Node<'s>> { if self.children.len() == 1 { Ok(&self.children[0]) } else if self.children.len() > 1 { Err(ElementError::MultipleChildren.into()) } 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 text_content(&self) -> Result> { let text = Vec::new(); for node in *self.children { match node { Node::Text(t) => text.push(t), _ => {} } } if text.is_empty() { Err(ElementError::NotText) } Ok(text) } 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(()) } #[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), Node::Unknown => Err(JabberError::UnexpectedElement), } } pub async fn read_start( 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 localname = str::from_utf8(e.local_name().into_inner())?; let mut namespaces = local_namespaces.clone(); let mut namespace_declarations = BTreeMap::new(); let attributes = BTreeMap::new(); for attribute in e.attributes() { let attribute = attribute?; if let Some(prefix_declaration) = attribute.key.as_namespace_binding() { match prefix_declaration { PrefixDeclaration::Default => { let value = str::from_utf8(attribute.value.as_ref())?; namespace_declarations.try_insert(None, value); namespaces.insert(None, value); } PrefixDeclaration::Named(prefix) => { let key = str::from_utf8(prefix)?; let value = str::from_utf8(attribute.value.as_ref())?; namespace_declarations .try_insert(Some(key), value) .map_err(ParseError::DuplicateAttribute)?; namespaces.insert(Some(key), value); } } } else { attributes .try_insert( str::from_utf8(attribute.key.into_inner())?, str::from_utf8(attribute.value.as_ref())?, ) .map_err(ParseError::DuplicateAttribute)?; } } let namespace = *namespaces.get(&prefix).ok_or(ParseError::NoNamespace)?; let mut children = Vec::new(); Ok(Some(Self::Element(Element { prefix, localname, namespace, namespace_declarations, attributes, children, }))) } e => Err(ElementError::NotAStart(e)), } } } impl<'s> Node<'s> { 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::Empty(e) => { let prefix = e .name() .prefix() .map(|prefix| str::from_utf8(prefix.into_inner())?); let localname = str::from_utf8(e.local_name().into_inner())?; let mut namespaces = local_namespaces.clone(); let mut namespace_declarations = BTreeMap::new(); let attributes = BTreeMap::new(); for attribute in e.attributes() { let attribute = attribute?; if let Some(prefix_declaration) = attribute.key.as_namespace_binding() { match prefix_declaration { PrefixDeclaration::Default => { let value = str::from_utf8(attribute.value.as_ref())?; namespace_declarations.try_insert(None, value); namespaces.insert(None, value); } PrefixDeclaration::Named(prefix) => { let key = str::from_utf8(prefix)?; let value = str::from_utf8(attribute.value.as_ref())?; namespace_declarations .try_insert(Some(key), value) .map_err(ParseError::DuplicateAttribute)?; namespaces.insert(Some(key), value); } } } else { attributes .try_insert( str::from_utf8(attribute.key.into_inner())?, str::from_utf8(attribute.value.as_ref())?, ) .map_err(ParseError::DuplicateAttribute)?; } } let namespace = *namespaces.get(&prefix).ok_or(ParseError::NoNamespace)?; let children = Vec::new(); Ok(Some(Self::Element(Element { prefix, localname, namespace, namespace_declarations, attributes, children, }))) } Event::Start(e) => { let prefix = e .name() .prefix() .map(|prefix| str::from_utf8(prefix.into_inner())?); let localname = str::from_utf8(e.local_name().into_inner())?; let mut namespaces = local_namespaces.clone(); let mut namespace_declarations = BTreeMap::new(); let attributes = BTreeMap::new(); for attribute in e.attributes() { let attribute = attribute?; if let Some(prefix_declaration) = attribute.key.as_namespace_binding() { match prefix_declaration { PrefixDeclaration::Default => { let value = str::from_utf8(attribute.value.as_ref())?; namespace_declarations.try_insert(None, value); namespaces.insert(None, value); } PrefixDeclaration::Named(prefix) => { let key = str::from_utf8(prefix)?; let value = str::from_utf8(attribute.value.as_ref())?; namespace_declarations .try_insert(Some(key), value) .map_err(ParseError::DuplicateAttribute)?; namespaces.insert(Some(key), value); } } } else { attributes .try_insert( str::from_utf8(attribute.key.into_inner())?, str::from_utf8(attribute.value.as_ref())?, ) .map_err(ParseError::DuplicateAttribute)?; } } let namespace = *namespaces.get(&prefix).ok_or(ParseError::NoNamespace)?; let mut children = Vec::new(); while let Some(child_node) = Node::read_recursive(reader, &namespaces).await? { children.push(child_node) } Ok(Some(Self::Element(Element { prefix, localname, namespace, namespace_declarations, attributes, children, }))) } Event::End(_) => Ok(None), Event::Text(e) => Ok(Some(Self::Text(e.unescape()?.as_ref()))), e => Ok(Some(Self::Unknown)), } } } // #[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, } #[derive(Debug)] pub enum ParseError { DuplicateAttribute, NoNamespace, }