xso: Add PrintRawXml helper struct with Display

Maxime “pep” Buquet created

Add a helper struct to be able to display Raw Xml, useful for debug
logs.

Signed-off-by: Maxime “pep” Buquet <pep@bouah.net>

Change summary

tokio-xmpp/src/lib.rs |  3 +++
xso/Cargo.toml        |  1 +
xso/src/asxml.rs      | 30 ++++++++++++++++++++++++++++++
xso/src/lib.rs        |  2 ++
4 files changed, 36 insertions(+)

Detailed changes

tokio-xmpp/src/lib.rs 🔗

@@ -81,3 +81,6 @@ mod tests {
         use crate::parsers;
     }
 }
+
+// Re-export for debug purposes
+pub use xso::asxml::PrintRawXml;

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 }

xso/src/asxml.rs 🔗

@@ -18,6 +18,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<T>` to XML.
 pub struct OptionAsXml<T: Iterator>(Option<T>);
 
@@ -97,6 +101,32 @@ 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, "<failed to serialize PrintRawXml: {:?}>", 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, "<failed to serialize PrintRawXml: {:?}>", err),
+            };
+            if let Err(err) = writer.encode(item.as_rxml_item(), &mut buf) {
+                return write!(f, "<failed to serialize PrintRawXml: {:?}>", err);
+            }
+        }
+        // TODO: rxml guarantees us that we have utf8 here. This unwrap can nonetheless be removed
+        // if Write is implemented for rxml.
+        write!(f, "{}", std::str::from_utf8(&buf).unwrap())
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;

xso/src/lib.rs 🔗

@@ -87,6 +87,8 @@ pub use text::TextCodec;
 #[doc(inline)]
 pub use rxml_util::Item;
 
+pub use asxml::PrintRawXml;
+
 #[doc = include_str!("from_xml_doc.md")]
 #[doc(inline)]
 #[cfg(feature = "macros")]