2023-07-11 21:28:42 +01:00
|
|
|
// use quick_xml::events::BytesDecl;
|
|
|
|
|
2023-08-02 00:56:38 +01:00
|
|
|
pub mod bind;
|
|
|
|
pub mod iq;
|
2023-07-04 21:27:15 +01:00
|
|
|
pub mod sasl;
|
2023-06-19 19:23:54 +01:00
|
|
|
pub mod stream;
|
2023-07-11 21:28:42 +01:00
|
|
|
|
2023-08-02 18:21:57 +01:00
|
|
|
use std::collections::BTreeMap;
|
2023-08-05 16:47:52 +01:00
|
|
|
use std::str;
|
2023-08-02 18:21:57 +01:00
|
|
|
|
2023-07-11 21:28:42 +01:00
|
|
|
// const DECLARATION: BytesDecl<'_> = BytesDecl::new("1.0", None, None);
|
2023-07-12 12:41:36 +01:00
|
|
|
use async_recursion::async_recursion;
|
2023-08-05 16:47:52 +01:00
|
|
|
use quick_xml::events::{BytesEnd, BytesStart, BytesText, Event};
|
2023-08-05 17:38:50 +01:00
|
|
|
use quick_xml::name::PrefixDeclaration;
|
2023-07-12 12:41:36 +01:00
|
|
|
use quick_xml::{Reader, Writer};
|
|
|
|
use tokio::io::{AsyncBufRead, AsyncWrite};
|
|
|
|
|
2023-08-05 16:47:52 +01:00
|
|
|
use crate::{JabberError, Result};
|
2023-07-12 12:41:36 +01:00
|
|
|
|
2023-08-02 18:21:57 +01:00
|
|
|
// #[derive(Clone, Debug)]
|
|
|
|
// pub struct EventTree<'e> {
|
|
|
|
// pub event: Event<'e>,
|
|
|
|
// pub children: Option<Vec<Element<'e>>>,
|
|
|
|
// }
|
|
|
|
|
|
|
|
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 `<foo:bar />`.
|
|
|
|
prefix: Option<&'s str>,
|
2023-08-05 16:47:52 +01:00
|
|
|
/// element name
|
|
|
|
/// e.g. `bar` in `<foo:bar />`.
|
|
|
|
localname: &'s str,
|
2023-08-02 18:21:57 +01:00
|
|
|
/// qualifying namespace
|
|
|
|
/// an element must be qualified by a namespace
|
|
|
|
/// e.g. for `<stream:features>` in
|
|
|
|
/// ```
|
|
|
|
/// <stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'>
|
|
|
|
/// <stream:features>
|
|
|
|
/// <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>
|
|
|
|
/// <compression xmlns='http://jabber.org/features/compress'>
|
|
|
|
/// <method>zlib</method>
|
|
|
|
/// <method>lzw</method>
|
|
|
|
/// </compression>
|
|
|
|
/// </stream:features>
|
|
|
|
/// </stream:stream>
|
|
|
|
/// ```
|
|
|
|
/// would be `"http://etherx.jabber.org/streams"` but for
|
|
|
|
/// ```
|
|
|
|
/// <stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'>
|
|
|
|
/// <features>
|
|
|
|
/// <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>
|
|
|
|
/// <compression xmlns='http://jabber.org/features/compress'>
|
|
|
|
/// <method>zlib</method>
|
|
|
|
/// <method>lzw</method>
|
|
|
|
/// </compression>
|
|
|
|
/// </features>
|
|
|
|
/// </stream:stream>
|
|
|
|
/// ```
|
|
|
|
/// would be `"jabber:client"`
|
|
|
|
namespace: &'s str,
|
|
|
|
/// all namespaces applied to element
|
|
|
|
/// e.g. for `<bind>` in
|
|
|
|
/// ```
|
|
|
|
/// <stream:features xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'>
|
|
|
|
/// <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>
|
|
|
|
/// <compression xmlns='http://jabber.org/features/compress'>
|
|
|
|
/// <method>zlib</method>
|
|
|
|
/// <method>lzw</method>
|
|
|
|
/// </compression>
|
|
|
|
/// </stream:features>
|
|
|
|
/// ```
|
|
|
|
/// would be `[(None, "urn:ietf:params:xml:ns:xmpp-bind")]` despite
|
|
|
|
/// `(Some("stream"), "http://etherx.jabber.org/streams")` also being available
|
2023-08-05 16:47:52 +01:00
|
|
|
namespace_declarations: Box<BTreeMap<Option<&'s str>, &'s str>>,
|
2023-08-02 18:21:57 +01:00
|
|
|
/// element attributes
|
|
|
|
attributes: Box<BTreeMap<&'s str, &'s str>>,
|
|
|
|
// children elements namespaces contain their parents' namespaces
|
2023-08-05 16:47:52 +01:00
|
|
|
children: Box<Vec<Node<'s>>>,
|
2023-08-02 18:21:57 +01:00
|
|
|
}
|
|
|
|
|
2023-07-12 21:11:20 +01:00
|
|
|
#[derive(Clone, Debug)]
|
2023-08-02 18:21:57 +01:00
|
|
|
pub enum Node<'s> {
|
|
|
|
Element(Element<'s>),
|
|
|
|
Text(&'s str),
|
2023-08-05 17:38:50 +01:00
|
|
|
Unknown,
|
2023-08-02 18:21:57 +01:00
|
|
|
}
|
|
|
|
|
2023-08-05 16:47:52 +01:00
|
|
|
impl<'s> From<&Node<'s>> for Vec<Event<'s>> {
|
|
|
|
fn from(node: &Node<'s>) -> Self {
|
|
|
|
match node {
|
|
|
|
Node::Element(e) => e.into(),
|
|
|
|
Node::Text(t) => vec![Event::Text(BytesText::new(t))],
|
2023-08-05 17:38:50 +01:00
|
|
|
Unknown => vec![],
|
2023-08-05 16:47:52 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'s> Element<'s> {
|
|
|
|
/// returns the fully qualified name
|
|
|
|
/// e.g. `foo:bar` in
|
|
|
|
/// `<foo:bar>`.
|
|
|
|
pub fn name(&self) -> &str {
|
|
|
|
if let Some(prefix) = self.prefix {
|
|
|
|
format!("{}:{}", prefix, self.localname).as_str()
|
2023-08-02 18:21:57 +01:00
|
|
|
} else {
|
2023-08-05 16:47:52 +01:00
|
|
|
self.localname
|
2023-08-02 18:21:57 +01:00
|
|
|
}
|
2023-08-05 16:47:52 +01:00
|
|
|
}
|
2023-08-02 18:21:57 +01:00
|
|
|
|
2023-08-05 16:47:52 +01:00
|
|
|
/// returns the localname.
|
|
|
|
/// e.g. `bar` in `<foo:bar>`
|
|
|
|
pub fn localname(&self) -> &str {
|
|
|
|
self.localname
|
|
|
|
}
|
2023-08-02 18:21:57 +01:00
|
|
|
|
2023-08-05 16:47:52 +01:00
|
|
|
/// returns the prefix.
|
|
|
|
/// e.g. `foo` in `<foo:bar>`. returns None if there is
|
|
|
|
/// no prefix.
|
|
|
|
pub fn prefix(&self) -> Option<&str> {
|
|
|
|
self.prefix
|
2023-08-02 18:21:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/// returns the namespace which applies to the current element, e.g. for
|
2023-08-05 16:47:52 +01:00
|
|
|
/// `<element xmlns='foo' xmlns:bar='bar'>`
|
|
|
|
/// it will be `foo` but for
|
|
|
|
/// `<bar:element xmlns='foo' xmlns:bar='bar'>`
|
|
|
|
/// it will be `bar`.
|
|
|
|
pub fn namespace(&self) -> &str {
|
2023-08-02 18:21:57 +01:00
|
|
|
self.namespace
|
|
|
|
}
|
2023-07-12 12:41:36 +01:00
|
|
|
}
|
|
|
|
|
2023-08-05 16:47:52 +01:00
|
|
|
impl<'s> From<&Element<'s>> for Vec<Event<'s>> {
|
|
|
|
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),
|
2023-08-02 18:21:57 +01:00
|
|
|
}
|
2023-08-05 16:47:52 +01:00
|
|
|
});
|
|
|
|
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<Event<'s>> = vec![Event::Start(event)];
|
|
|
|
let start_and_content: Vec<Event<'s>> = start
|
|
|
|
.into_iter()
|
|
|
|
.chain({
|
|
|
|
let u = element.children.iter().fold(
|
|
|
|
Vec::new(),
|
|
|
|
|acc: Vec<Event<'s>>, child: &Node<'s>| {
|
|
|
|
acc.into_iter()
|
|
|
|
.chain(Into::<Vec<Event<'s>>>::into(child).into_iter())
|
|
|
|
.collect()
|
|
|
|
},
|
|
|
|
);
|
|
|
|
u
|
|
|
|
})
|
|
|
|
.collect();
|
|
|
|
let full: Vec<Event<'s>> = start_and_content
|
|
|
|
.into_iter()
|
|
|
|
.chain(vec![Event::End(BytesEnd::new(name))])
|
|
|
|
.collect();
|
|
|
|
full
|
2023-07-12 12:41:36 +01:00
|
|
|
}
|
|
|
|
}
|
2023-08-05 16:47:52 +01:00
|
|
|
}
|
2023-07-12 12:41:36 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-08-05 16:47:52 +01:00
|
|
|
impl<'s> Element<'s> {
|
|
|
|
/// if there is only one child in the vec of children, will return that element
|
2023-08-05 17:38:50 +01:00
|
|
|
pub fn child(&self) -> Result<&Node<'s>> {
|
2023-08-05 16:47:52 +01:00
|
|
|
if self.children.len() == 1 {
|
|
|
|
Ok(&self.children[0])
|
2023-08-05 17:38:50 +01:00
|
|
|
} else if self.children.len() > 1 {
|
|
|
|
Err(ElementError::MultipleChildren.into())
|
2023-08-05 16:47:52 +01:00
|
|
|
} else {
|
|
|
|
Err(ElementError::NoChildren.into())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// returns reference to children
|
2023-08-05 17:38:50 +01:00
|
|
|
pub fn children(&self) -> Result<&Vec<Node<'s>>> {
|
2023-08-05 16:47:52 +01:00
|
|
|
if !self.children.is_empty() {
|
|
|
|
Ok(&self.children)
|
|
|
|
} else {
|
|
|
|
Err(ElementError::NoChildren.into())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// returns text content, error if there is none
|
2023-08-05 17:38:50 +01:00
|
|
|
pub fn text_content(&self) -> Result<Vec<&str>> {
|
|
|
|
let text = Vec::new();
|
2023-08-05 16:47:52 +01:00
|
|
|
for node in *self.children {
|
|
|
|
match node {
|
2023-08-05 17:38:50 +01:00
|
|
|
Node::Text(t) => text.push(t),
|
2023-08-05 16:47:52 +01:00
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
}
|
2023-08-05 17:38:50 +01:00
|
|
|
if text.is_empty() {
|
|
|
|
Err(ElementError::NotText)
|
|
|
|
}
|
|
|
|
Ok(text)
|
2023-08-05 16:47:52 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn write<W: AsyncWrite + Unpin + Send>(&self, writer: &mut Writer<W>) -> Result<()> {
|
|
|
|
let events: Vec<Event> = self.into();
|
|
|
|
for event in events {
|
|
|
|
writer.write_event_async(event).await?
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2023-07-12 12:41:36 +01:00
|
|
|
pub async fn write_start<W: AsyncWrite + Unpin + Send>(
|
|
|
|
&self,
|
|
|
|
writer: &mut Writer<W>,
|
2023-08-05 16:47:52 +01:00
|
|
|
) -> 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(())
|
2023-07-12 12:41:36 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn write_end<W: AsyncWrite + Unpin + Send>(
|
|
|
|
&self,
|
|
|
|
writer: &mut Writer<W>,
|
2023-08-05 16:47:52 +01:00
|
|
|
) -> Result<()> {
|
|
|
|
let event = BytesEnd::new(self.name());
|
|
|
|
writer.write_event_async(Event::End(event)).await?;
|
|
|
|
Ok(())
|
2023-07-12 12:41:36 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
#[async_recursion]
|
|
|
|
pub async fn read<R: AsyncBufRead + Unpin + Send>(
|
|
|
|
reader: &mut Reader<R>,
|
2023-08-05 17:38:50 +01:00
|
|
|
local_namespaces: &BTreeMap<Option<&str>, &str>,
|
2023-08-05 16:47:52 +01:00
|
|
|
) -> Result<Self> {
|
|
|
|
let node = Node::read_recursive(reader, local_namespaces)
|
2023-07-12 21:11:20 +01:00
|
|
|
.await?
|
2023-08-05 16:47:52 +01:00
|
|
|
.ok_or(JabberError::UnexpectedEnd)?;
|
|
|
|
match node {
|
|
|
|
Node::Element(e) => Ok(e),
|
|
|
|
Node::Text(_) => Err(JabberError::UnexpectedText),
|
2023-08-05 17:38:50 +01:00
|
|
|
Node::Unknown => Err(JabberError::UnexpectedElement),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
pub async fn read_start<R: AsyncBufRead + Unpin + Send>(
|
|
|
|
reader: &mut Reader<R>,
|
|
|
|
local_namespaces: &BTreeMap<Option<&str>, &str>,
|
|
|
|
) -> Result<Self> {
|
|
|
|
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)),
|
2023-08-05 16:47:52 +01:00
|
|
|
}
|
2023-07-12 21:11:20 +01:00
|
|
|
}
|
2023-08-05 16:47:52 +01:00
|
|
|
}
|
2023-07-12 21:11:20 +01:00
|
|
|
|
2023-08-05 16:47:52 +01:00
|
|
|
impl<'s> Node<'s> {
|
2023-07-12 21:11:20 +01:00
|
|
|
async fn read_recursive<R: AsyncBufRead + Unpin + Send>(
|
|
|
|
reader: &mut Reader<R>,
|
2023-08-05 17:38:50 +01:00
|
|
|
local_namespaces: &BTreeMap<Option<&str>, &str>,
|
2023-08-05 16:47:52 +01:00
|
|
|
) -> Result<Option<Node<'s>>> {
|
2023-07-12 12:41:36 +01:00
|
|
|
let mut buf = Vec::new();
|
|
|
|
let event = reader.read_event_into_async(&mut buf).await?;
|
|
|
|
match event {
|
2023-08-05 17:38:50 +01:00
|
|
|
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,
|
|
|
|
})))
|
|
|
|
}
|
2023-07-12 12:41:36 +01:00
|
|
|
Event::Start(e) => {
|
2023-08-05 16:47:52 +01:00
|
|
|
let prefix = e
|
|
|
|
.name()
|
|
|
|
.prefix()
|
|
|
|
.map(|prefix| str::from_utf8(prefix.into_inner())?);
|
2023-08-05 17:38:50 +01:00
|
|
|
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)?;
|
|
|
|
}
|
|
|
|
}
|
2023-08-05 16:47:52 +01:00
|
|
|
|
2023-08-05 17:38:50 +01:00
|
|
|
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)
|
2023-07-12 12:41:36 +01:00
|
|
|
}
|
2023-08-05 17:38:50 +01:00
|
|
|
|
2023-08-05 16:47:52 +01:00
|
|
|
Ok(Some(Self::Element(Element {
|
|
|
|
prefix,
|
2023-08-05 17:38:50 +01:00
|
|
|
localname,
|
|
|
|
namespace,
|
|
|
|
namespace_declarations,
|
|
|
|
attributes,
|
|
|
|
children,
|
2023-08-05 16:47:52 +01:00
|
|
|
})))
|
2023-07-12 12:41:36 +01:00
|
|
|
}
|
|
|
|
Event::End(_) => Ok(None),
|
2023-08-05 16:47:52 +01:00
|
|
|
Event::Text(e) => Ok(Some(Self::Text(e.unescape()?.as_ref()))),
|
2023-08-05 17:38:50 +01:00
|
|
|
e => Ok(Some(Self::Unknown)),
|
2023-07-12 12:41:36 +01:00
|
|
|
}
|
|
|
|
}
|
2023-07-12 21:11:20 +01:00
|
|
|
}
|
|
|
|
|
2023-08-05 16:47:52 +01:00
|
|
|
// #[async_recursion]
|
|
|
|
// pub async fn read_start<R: AsyncBufRead + Unpin + Send>(
|
|
|
|
// reader: &mut Reader<R>,
|
|
|
|
// ) -> Result<Self, JabberError> {
|
|
|
|
// 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()),
|
|
|
|
// }
|
|
|
|
// }
|
2023-08-02 00:56:38 +01:00
|
|
|
|
2023-08-05 16:47:52 +01:00
|
|
|
// pub trait IntoElement<'e> {
|
|
|
|
// fn event(&self) -> Event<'e>;
|
|
|
|
// fn children(&self) -> Option<Vec<Element<'e>>>;
|
|
|
|
// }
|
|
|
|
|
|
|
|
// impl<'e, T: IntoElement<'e>> From<T> for Element<'e> {
|
|
|
|
// fn from(value: T) -> Self {
|
|
|
|
// Element {
|
|
|
|
// event: value.event(),
|
|
|
|
// children: value.children(),
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// }
|
2023-07-12 21:11:20 +01:00
|
|
|
|
2023-07-12 12:41:36 +01:00
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum ElementError<'e> {
|
|
|
|
NotAStart(Event<'e>),
|
2023-08-05 16:47:52 +01:00
|
|
|
NotText,
|
2023-07-12 21:11:20 +01:00
|
|
|
NoChildren,
|
|
|
|
MultipleChildren,
|
2023-07-12 12:41:36 +01:00
|
|
|
}
|
2023-08-05 17:38:50 +01:00
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum ParseError {
|
|
|
|
DuplicateAttribute,
|
|
|
|
NoNamespace,
|
|
|
|
}
|