Add a Stream Management implementation.

Emmanuel Gil Peyrot created

Change summary

src/lib.rs |   3 +
src/ns.rs  |   3 +
src/sm.rs  | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 119 insertions(+)

Detailed changes

src/lib.rs 🔗

@@ -119,6 +119,9 @@ pub mod receipts;
 /// XEP-0191: Blocking Command
 pub mod blocking;
 
+/// XEP-0198: Stream Management
+pub mod sm;
+
 /// XEP-0199: XMPP Ping
 pub mod ping;
 

src/ns.rs 🔗

@@ -85,6 +85,9 @@ pub const BLOCKING: &str = "urn:xmpp:blocking";
 /// XEP-0191: Blocking Command
 pub const BLOCKING_ERRORS: &str = "urn:xmpp:blocking:errors";
 
+/// XEP-0198: Stream Management
+pub const SM: &str = "urn:xmpp:sm:3";
+
 /// XEP-0199: XMPP Ping
 pub const PING: &str = "urn:xmpp:ping";
 

src/sm.rs 🔗

@@ -0,0 +1,113 @@
+// Copyright (c) 2018 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+use stanza_error::DefinedCondition;
+
+generate_element_with_only_attributes!(
+    A, "a", SM, [
+        h: u32 = "h" => required,
+    ]
+);
+
+impl A {
+    pub fn new(h: u32) -> A {
+        A { h }
+    }
+}
+
+generate_attribute!(ResumeAttr, "resume", bool);
+
+generate_element_with_only_attributes!(
+    Enable, "enable", SM, [
+        // TODO: should be the infinite integer set ≥ 1.
+        max: Option<u32> = "max" => optional,
+        resume: ResumeAttr = "resume" => default,
+    ]
+);
+
+impl Enable {
+    pub fn new() -> Self {
+        Enable {
+            max: None,
+            resume: ResumeAttr::False,
+        }
+    }
+
+    pub fn with_max(mut self, max: u32) -> Self {
+        self.max = Some(max);
+        self
+    }
+
+    pub fn with_resume(mut self) -> Self {
+        self.resume = ResumeAttr::True;
+        self
+    }
+}
+
+generate_element_with_only_attributes!(
+    Enabled, "enabled", SM, [
+        id: Option<String> = "id" => optional,
+        location: Option<String> = "location" => optional,
+        // TODO: should be the infinite integer set ≥ 1.
+        max: Option<u32> = "max" => optional,
+        resume: ResumeAttr = "resume" => default,
+    ]
+);
+
+generate_element_with_children!(
+    Failed, "failed", SM,
+    attributes: [
+        h: Option<u32> = "h" => optional,
+    ],
+    child: (
+        // XXX: implement the * handling.
+        error: Option<DefinedCondition> = ("*", XMPP_STANZAS) => DefinedCondition
+    )
+);
+
+generate_empty_element!(
+    R, "r", SM
+);
+
+generate_element_with_only_attributes!(
+    Resume, "resume", SM, [
+        h: u32 = "h" => required,
+        previd: String = "previd" => required,
+    ]
+);
+
+generate_element_with_only_attributes!(
+    Resumed, "resumed", SM, [
+        h: u32 = "h" => required,
+        previd: String = "previd" => required,
+    ]
+);
+
+// TODO: add support for optional and required.
+generate_empty_element!(
+    /// Represents availability of Stream Management in `<stream:features/>`.
+    StreamManagement, "sm", SM
+);
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use try_from::TryFrom;
+    use minidom::Element;
+
+    #[test]
+    fn a() {
+        let elem: Element = "<a xmlns='urn:xmpp:sm:3' h='5'".parse().unwrap();
+        let a = A::try_from(elem).unwrap();
+        assert_eq!(a.h, 5);
+    }
+
+    #[test]
+    fn stream_feature() {
+        let elem: Element = "<sm xmlns='urn:xmpp:sm:3'/>".parse().unwrap();
+        StreamManagement::try_from(elem).unwrap();
+    }
+}