xmlstream: add support for boxing the transport

Jonas Schäfer created

This is useful in situations where we don't want to care about the
specific type of the underlying transport.

Change summary

tokio-xmpp/src/xmlstream/common.rs | 27 +++++++++++++++++++++++++++
tokio-xmpp/src/xmlstream/mod.rs    | 17 +++++++++++++++++
2 files changed, 44 insertions(+)

Detailed changes

tokio-xmpp/src/xmlstream/common.rs 🔗

@@ -25,6 +25,8 @@ use xso::{
     AsXml, FromEventsBuilder, FromXml, Item,
 };
 
+use crate::connect::AsyncReadAndWrite;
+
 use super::capture::{log_enabled, log_recv, log_send, CaptureBufRead};
 
 use xmpp_parsers::ns::STREAM as XML_STREAM_NS;
@@ -272,6 +274,31 @@ impl<Io: AsyncBufRead + AsyncWrite> RawXmlStream<Io> {
     pub(super) fn into_inner(self) -> Io {
         self.parser.into_inner().0.into_inner()
     }
+
+    /// Box the underlying transport stream.
+    ///
+    /// This removes the specific type of the transport from the XML stream's
+    /// type signature.
+    pub(super) fn box_stream(self) -> RawXmlStream<Box<dyn AsyncReadAndWrite + Send + 'static>>
+    where
+        Io: AsyncReadAndWrite + Send + 'static,
+    {
+        let (io, p) = self.parser.into_inner();
+        let mut io = CaptureBufRead::wrap(Box::new(io) as Box<_>);
+        if log_enabled() {
+            io.enable_capture();
+        }
+        let parser = rxml::AsyncReader::wrap(io, p);
+        RawXmlStream {
+            parser,
+            timeouts: self.timeouts,
+            writer: self.writer,
+            tx_buffer: self.tx_buffer,
+            tx_buffer_logged: self.tx_buffer_logged,
+            tx_buffer_high_water_mark: self.tx_buffer_high_water_mark,
+            stream_ns: self.stream_ns,
+        }
+    }
 }
 
 impl<Io: AsyncWrite> RawXmlStream<Io> {

tokio-xmpp/src/xmlstream/mod.rs 🔗

@@ -70,6 +70,8 @@ use tokio::io::{AsyncBufRead, AsyncWrite};
 
 use xso::{AsXml, FromXml, Item};
 
+use crate::connect::AsyncReadAndWrite;
+
 mod capture;
 mod common;
 mod initiator;
@@ -337,6 +339,21 @@ impl<Io: AsyncBufRead + AsyncWrite + Unpin, T: FromXml + AsXml + fmt::Debug> Xml
         self.assert_retypable();
         self.inner.into_inner()
     }
+
+    /// Box the underlying transport stream.
+    ///
+    /// This removes the specific type of the transport from the XML stream's
+    /// type signature.
+    pub fn box_stream(self) -> XmlStream<Box<dyn AsyncReadAndWrite + Send + 'static>, T>
+    where
+        Io: AsyncReadAndWrite + Send + 'static,
+    {
+        XmlStream {
+            inner: self.inner.box_stream(),
+            read_state: self.read_state,
+            write_state: self.write_state,
+        }
+    }
 }
 
 impl<Io: AsyncBufRead, T: FromXml + AsXml + fmt::Debug> Stream for XmlStream<Io, T> {