WIP: refactor Element type
This commit is contained in:
parent
cd7bb95c0a
commit
2a7b8834d7
|
@ -85,6 +85,13 @@ impl<'j> JabberClient<'j> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn watch(&mut self) -> Result<()> {
|
||||||
|
loop {
|
||||||
|
let element = Element::read(&mut self.reader).await?;
|
||||||
|
println!("{:#?}", element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn sasl(&mut self, mechanisms: &Vec<String>) -> Result<()> {
|
pub async fn sasl(&mut self, mechanisms: &Vec<String>) -> Result<()> {
|
||||||
println!("{:?}", mechanisms);
|
println!("{:?}", mechanisms);
|
||||||
let sasl = SASLClient::new(self.jabber.auth.clone());
|
let sasl = SASLClient::new(self.jabber.auth.clone());
|
||||||
|
|
|
@ -52,6 +52,9 @@ mod tests {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.login()
|
.login()
|
||||||
.await
|
.await
|
||||||
|
.unwrap()
|
||||||
|
.watch()
|
||||||
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,18 +5,117 @@ pub mod iq;
|
||||||
pub mod sasl;
|
pub mod sasl;
|
||||||
pub mod stream;
|
pub mod stream;
|
||||||
|
|
||||||
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
// const DECLARATION: BytesDecl<'_> = BytesDecl::new("1.0", None, None);
|
// const DECLARATION: BytesDecl<'_> = BytesDecl::new("1.0", None, None);
|
||||||
use async_recursion::async_recursion;
|
use async_recursion::async_recursion;
|
||||||
use quick_xml::events::Event;
|
use quick_xml::events::{BytesStart, Event};
|
||||||
use quick_xml::{Reader, Writer};
|
use quick_xml::{Reader, Writer};
|
||||||
use tokio::io::{AsyncBufRead, AsyncWrite};
|
use tokio::io::{AsyncBufRead, AsyncWrite};
|
||||||
|
|
||||||
use crate::JabberError;
|
use crate::JabberError;
|
||||||
|
|
||||||
|
// #[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)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Element<'e> {
|
/// represents an xml element as a tree of nodes
|
||||||
pub event: Event<'e>,
|
pub struct Element<'s> {
|
||||||
pub children: Option<Vec<Element<'e>>>,
|
/// element prefix
|
||||||
|
/// e.g. `foo` in `<foo:bar />`.
|
||||||
|
prefix: Option<&'s str>,
|
||||||
|
/// 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,
|
||||||
|
/// element name
|
||||||
|
/// e.g. `bar` in `<foo:bar />`.
|
||||||
|
name: &'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
|
||||||
|
namespaces: Box<BTreeMap<Option<&'s str>, &'s str>>,
|
||||||
|
/// element attributes
|
||||||
|
attributes: Box<BTreeMap<&'s str, &'s str>>,
|
||||||
|
// children elements namespaces contain their parents' namespaces
|
||||||
|
///
|
||||||
|
children: Option<Box<Vec<Node<'s>>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub enum Node<'s> {
|
||||||
|
Element(Element<'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> Element<'s> {
|
||||||
|
/// returns the namespace which applies to the current element, e.g. for
|
||||||
|
/// `<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'>`
|
||||||
|
/// it will be `http://etherx.jabber.org/streams` but for
|
||||||
|
/// `<stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'>`
|
||||||
|
/// it will be `jabber:client`.
|
||||||
|
pub fn get_namespace(&self) -> &str {
|
||||||
|
self.namespace
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'e: 'async_recursion, 'async_recursion> Element<'e> {
|
impl<'e: 'async_recursion, 'async_recursion> Element<'e> {
|
||||||
|
@ -35,6 +134,9 @@ impl<'e: 'async_recursion, 'async_recursion> Element<'e> {
|
||||||
'life0: 'async_recursion,
|
'life0: 'async_recursion,
|
||||||
{
|
{
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
|
match &self.children.is_empty() {
|
||||||
|
true => {}
|
||||||
|
}
|
||||||
match &self.event {
|
match &self.event {
|
||||||
Event::Start(e) => {
|
Event::Start(e) => {
|
||||||
writer.write_event_async(Event::Start(e.clone())).await?;
|
writer.write_event_async(Event::Start(e.clone())).await?;
|
||||||
|
|
Loading…
Reference in New Issue