diff --git a/tokio-xmpp/src/event.rs b/tokio-xmpp/src/event.rs index 58d5b26d..296428ff 100644 --- a/tokio-xmpp/src/event.rs +++ b/tokio-xmpp/src/event.rs @@ -6,6 +6,7 @@ use rand::{thread_rng, Rng}; use xmpp_parsers::{iq::Iq, jid::Jid, message::Message, presence::Presence}; +use xso::AsXml; use crate::xmlstream::XmppStreamElement; use crate::Error; @@ -16,15 +17,19 @@ fn make_id() -> String { } /// A stanza sent/received over the stream. -#[derive(Debug)] +#[derive(AsXml, Debug)] +#[xml()] pub enum Stanza { /// IQ stanza + #[xml(transparent)] Iq(Iq), /// Message stanza + #[xml(transparent)] Message(Message), /// Presence stanza + #[xml(transparent)] Presence(Presence), } diff --git a/tokio-xmpp/src/lib.rs b/tokio-xmpp/src/lib.rs index 5b00e42f..1c9200bb 100644 --- a/tokio-xmpp/src/lib.rs +++ b/tokio-xmpp/src/lib.rs @@ -70,3 +70,6 @@ pub use crate::error::Error; pub use minidom; pub use xmpp_parsers as parsers; pub use xmpp_parsers::jid; + +// Re-export for debug purposes +pub use xso::asxml::PrintRawXml; diff --git a/xso/Cargo.toml b/xso/Cargo.toml index 17083b25..8302e3da 100644 --- a/xso/Cargo.toml +++ b/xso/Cargo.toml @@ -10,6 +10,7 @@ categories = ["encoding"] license = "MPL-2.0" [dependencies] +bytes = { version = "1" } rxml = { version = "0.12.0", default-features = false } minidom = { version = "0.16", path = "../minidom" } xso_proc = { version = "0.1", path = "../xso-proc", optional = true } diff --git a/xso/src/asxml.rs b/xso/src/asxml.rs index 3b4e449e..8e3ef3d9 100644 --- a/xso/src/asxml.rs +++ b/xso/src/asxml.rs @@ -16,6 +16,10 @@ use crate::error::Error; use crate::rxml_util::Item; use crate::AsXml; +use core::fmt; + +use bytes::BytesMut; + /// Helper iterator to convert an `Option` to XML. pub struct OptionAsXml(Option); @@ -86,6 +90,30 @@ where } } +/// Provides a helper which implements Display printing raw XML +pub struct PrintRawXml<'x, T>(pub &'x T); + +impl<'x, T: AsXml> fmt::Display for PrintRawXml<'x, T> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let iter = match self.0.as_xml_iter() { + Ok(iter) => iter, + Err(err) => return write!(f, "", err), + }; + let mut writer = rxml::writer::Encoder::new(); + let mut buf = BytesMut::new(); + for item in iter { + let item = match item { + Ok(item) => item, + Err(err) => return write!(f, "", err), + }; + if let Err(err) = writer.encode(item.as_rxml_item(), &mut buf) { + return write!(f, "", err); + } + } + write!(f, "{:?}", buf) + } +} + #[cfg(test)] mod tests { use super::*;