diff --git a/src/error.rs b/src/error.rs
index a912840..8aa98ae 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -25,6 +25,7 @@ pub enum JabberError {
ParseError,
UnexpectedEnd,
UnexpectedElement,
+ UnexpectedText,
XML(quick_xml::Error),
SASL(SASLError),
Element(ElementError<'static>),
diff --git a/src/stanza/mod.rs b/src/stanza/mod.rs
index 8251422..7f4790d 100644
--- a/src/stanza/mod.rs
+++ b/src/stanza/mod.rs
@@ -6,14 +6,15 @@ 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::{BytesStart, Event};
+use quick_xml::events::{BytesEnd, BytesStart, BytesText, Event};
use quick_xml::{Reader, Writer};
use tokio::io::{AsyncBufRead, AsyncWrite};
-use crate::JabberError;
+use crate::{JabberError, Result};
// #[derive(Clone, Debug)]
// pub struct EventTree<'e> {
@@ -29,6 +30,9 @@ 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
@@ -57,9 +61,6 @@ pub struct Element<'s> {
/// ```
/// would be `"jabber:client"`
namespace: &'s str,
- /// element name
- /// e.g. `bar` in ``.
- name: &'s str,
/// all namespaces applied to element
/// e.g. for `` in
/// ```
@@ -73,12 +74,11 @@ pub struct Element<'s> {
/// ```
/// would be `[(None, "urn:ietf:params:xml:ns:xmpp-bind")]` despite
/// `(Some("stream"), "http://etherx.jabber.org/streams")` also being available
- namespaces: Box, &'s str>>,
+ namespace_declarations: Box, &'s str>>,
/// element attributes
attributes: Box>,
// children elements namespaces contain their parents' namespaces
- ///
- children: Option>>>,
+ children: Box>>,
}
#[derive(Clone, Debug)]
@@ -87,190 +87,281 @@ pub enum Node<'s> {
Text(&'s str),
}
-impl<'s> From<&Element<'s>> for Event<'s> {
- fn from(element: &Element<'s>) -> Self {
- let event;
- if let Some(prefix) = element.prefix {
- event = BytesStart::new(format!("{}:{}", prefix, element.name));
- } else {
- event = BytesStart::new(element.name);
- }
-
- event
-
- let event = event.with_attributes(element.attributes.into_iter());
-
- match element.children.is_none() {
- true => return Event::Empty(event),
- false => return Event::Start(event),
+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 `http://etherx.jabber.org/streams` but for
- /// ``
- /// it will be `jabber:client`.
- pub fn get_namespace(&self) -> &str {
+ /// ``
+ /// it will be `foo` but for
+ /// ``
+ /// it will be `bar`.
+ pub fn namespace(&self) -> &str {
self.namespace
}
}
-impl<'e: 'async_recursion, 'async_recursion> Element<'e> {
- pub fn write<'life0, W: AsyncWrite + Unpin + Send>(
- &'async_recursion self,
- writer: &'life0 mut Writer,
- ) -> ::core::pin::Pin<
- Box<
- dyn ::core::future::Future