websocket.rs

  1// Copyright (c) 2018 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
  2//
  3// This Source Code Form is subject to the terms of the Mozilla Public
  4// License, v. 2.0. If a copy of the MPL was not distributed with this
  5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
  6
  7use xso::{AsXml, FromXml};
  8
  9use jid::BareJid;
 10
 11use crate::ns;
 12
 13/// The stream opening for WebSocket.
 14#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
 15#[xml(namespace = ns::WEBSOCKET, name = "open")]
 16pub struct Open {
 17    /// The JID of the entity opening this stream.
 18    #[xml(attribute(default))]
 19    pub from: Option<BareJid>,
 20
 21    /// The JID of the entity receiving this stream opening.
 22    #[xml(attribute(default))]
 23    pub to: Option<BareJid>,
 24
 25    /// The id of the stream, used for authentication challenges.
 26    #[xml(attribute(default))]
 27    pub id: Option<String>,
 28
 29    /// The XMPP version used during this stream.
 30    #[xml(attribute(default))]
 31    pub version: Option<String>,
 32
 33    /// The default human language for all subsequent stanzas, which will
 34    /// be transmitted to other entities for better localisation.
 35    #[xml(lang(default))]
 36    pub xml_lang: Option<String>,
 37}
 38
 39impl Open {
 40    /// Creates a simple client→server `<open/>` element.
 41    pub fn new(to: BareJid) -> Open {
 42        Open {
 43            from: None,
 44            to: Some(to),
 45            id: None,
 46            version: Some(String::from("1.0")),
 47            xml_lang: None,
 48        }
 49    }
 50
 51    /// Sets the [@from](#structfield.from) attribute on this `<open/>`
 52    /// element.
 53    pub fn with_from(mut self, from: BareJid) -> Open {
 54        self.from = Some(from);
 55        self
 56    }
 57
 58    /// Sets the [@id](#structfield.id) attribute on this `<open/>` element.
 59    pub fn with_id(mut self, id: String) -> Open {
 60        self.id = Some(id);
 61        self
 62    }
 63
 64    /// Sets the [@xml:lang](#structfield.xml_lang) attribute on this `<open/>`
 65    /// element.
 66    pub fn with_lang(mut self, xml_lang: String) -> Open {
 67        self.xml_lang = Some(xml_lang);
 68        self
 69    }
 70
 71    /// Checks whether the version matches the expected one.
 72    pub fn is_version(&self, version: &str) -> bool {
 73        match self.version {
 74            None => false,
 75            Some(ref self_version) => self_version == &String::from(version),
 76        }
 77    }
 78}
 79
 80#[cfg(test)]
 81mod tests {
 82    use super::*;
 83    use minidom::Element;
 84
 85    #[cfg(target_pointer_width = "32")]
 86    #[test]
 87    fn test_size() {
 88        assert_size!(Open, 68);
 89    }
 90
 91    #[cfg(target_pointer_width = "64")]
 92    #[test]
 93    fn test_size() {
 94        assert_size!(Open, 136);
 95    }
 96
 97    #[test]
 98    fn test_simple() {
 99        let elem: Element = "<open xmlns='urn:ietf:params:xml:ns:xmpp-framing'/>"
100            .parse()
101            .unwrap();
102        let open = Open::try_from(elem).unwrap();
103        assert_eq!(open.from, None);
104        assert_eq!(open.to, None);
105        assert_eq!(open.id, None);
106        assert_eq!(open.version, None);
107        assert_eq!(open.xml_lang, None);
108    }
109}