tokio-xmpp: Automatically add id on send if not present

Maxime “pep” Buquet created

Based on Yuka's work in !149, but moved into tokio-xmpp instead of
xmpp-rs

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

Change summary

tokio-xmpp/Cargo.toml         |  1 +
tokio-xmpp/src/xmpp_stream.rs | 12 +++++++++++-
2 files changed, 12 insertions(+), 1 deletion(-)

Detailed changes

tokio-xmpp/Cargo.toml 🔗

@@ -29,6 +29,7 @@ xmpp-parsers = "0.19"
 minidom = "0.15"
 rxml = "^0.8.0"
 webpki-roots = { version = "0.22", optional = true }
+rand = "^0.8"
 
 [build-dependencies]
 rustc_version = "0.4"

tokio-xmpp/src/xmpp_stream.rs 🔗

@@ -2,6 +2,7 @@
 
 use futures::sink::Send;
 use futures::{sink::SinkExt, task::Poll, Sink, Stream};
+use rand::{thread_rng, Rng};
 use std::pin::Pin;
 use std::task::Context;
 use tokio::io::{AsyncRead, AsyncWrite};
@@ -13,6 +14,11 @@ use crate::stream_start;
 use crate::xmpp_codec::{Packet, XMPPCodec};
 use crate::Error;
 
+fn make_id() -> String {
+    let id: u64 = thread_rng().gen();
+    format!("{}", id)
+}
+
 /// Wraps a binary stream (tokio's `AsyncRead + AsyncWrite`) to decode
 /// and encode XMPP packets.
 ///
@@ -72,7 +78,11 @@ impl<S: AsyncRead + AsyncWrite + Unpin> XMPPStream<S> {
 impl<S: AsyncRead + AsyncWrite + Unpin> XMPPStream<S> {
     /// Convenience method
     pub fn send_stanza<E: Into<Element>>(&mut self, e: E) -> Send<Self, Packet> {
-        self.send(Packet::Stanza(e.into()))
+        let mut el: Element = e.into();
+        if el.attr("id").is_none() {
+            el.set_attr("id", make_id());
+        }
+        self.send(Packet::Stanza(el))
     }
 }