jingle_ibb.rs

  1// Copyright (c) 2017 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 std::convert::TryFrom;
  8
  9use minidom::Element;
 10
 11use error::Error;
 12
 13use ns;
 14
 15use ibb::Stanza;
 16
 17#[derive(Debug, Clone)]
 18pub struct Transport {
 19    pub block_size: u16,
 20    pub sid: String,
 21    pub stanza: Stanza,
 22}
 23
 24impl TryFrom<Element> for Transport {
 25    type Error = Error;
 26
 27    fn try_from(elem: Element) -> Result<Transport, Error> {
 28        if !elem.is("transport", ns::JINGLE_IBB) {
 29            return Err(Error::ParseError("This is not an JingleIBB element."))
 30        }
 31        for _ in elem.children() {
 32            return Err(Error::ParseError("Unknown child in JingleIBB element."));
 33        }
 34        Ok(Transport {
 35            block_size: get_attr!(elem, "block-size", required),
 36            sid: get_attr!(elem, "sid", required),
 37            stanza: get_attr!(elem, "stanza", default),
 38        })
 39    }
 40}
 41
 42impl Into<Element> for Transport {
 43    fn into(self) -> Element {
 44        Element::builder("transport")
 45                .ns(ns::JINGLE_IBB)
 46                .attr("block-size", format!("{}", self.block_size))
 47                .attr("sid", self.sid)
 48                .attr("stanza", self.stanza)
 49                .build()
 50    }
 51}
 52
 53#[cfg(test)]
 54mod tests {
 55    use super::*;
 56    use std::error::Error as StdError;
 57
 58    #[test]
 59    fn test_simple() {
 60        let elem: Element = "<transport xmlns='urn:xmpp:jingle:transports:ibb:1' block-size='3' sid='coucou'/>".parse().unwrap();
 61        let transport = Transport::try_from(elem).unwrap();
 62        assert_eq!(transport.block_size, 3);
 63        assert_eq!(transport.sid, "coucou");
 64        assert_eq!(transport.stanza, Stanza::Iq);
 65    }
 66
 67    #[test]
 68    fn test_invalid() {
 69        let elem: Element = "<transport xmlns='urn:xmpp:jingle:transports:ibb:1'/>".parse().unwrap();
 70        let error = Transport::try_from(elem).unwrap_err();
 71        let message = match error {
 72            Error::ParseError(string) => string,
 73            _ => panic!(),
 74        };
 75        assert_eq!(message, "Required attribute 'block-size' missing.");
 76
 77        let elem: Element = "<transport xmlns='urn:xmpp:jingle:transports:ibb:1' block-size='65536'/>".parse().unwrap();
 78        let error = Transport::try_from(elem).unwrap_err();
 79        let message = match error {
 80            Error::ParseIntError(error) => error,
 81            _ => panic!(),
 82        };
 83        assert_eq!(message.description(), "number too large to fit in target type");
 84
 85        let elem: Element = "<transport xmlns='urn:xmpp:jingle:transports:ibb:1' block-size='-5'/>".parse().unwrap();
 86        let error = Transport::try_from(elem).unwrap_err();
 87        let message = match error {
 88            Error::ParseIntError(error) => error,
 89            _ => panic!(),
 90        };
 91        assert_eq!(message.description(), "invalid digit found in string");
 92
 93        let elem: Element = "<transport xmlns='urn:xmpp:jingle:transports:ibb:1' block-size='128'/>".parse().unwrap();
 94        let error = Transport::try_from(elem).unwrap_err();
 95        let message = match error {
 96            Error::ParseError(string) => string,
 97            _ => panic!(),
 98        };
 99        assert_eq!(message, "Required attribute 'sid' missing.");
100    }
101
102    #[test]
103    fn test_invalid_stanza() {
104        let elem: Element = "<transport xmlns='urn:xmpp:jingle:transports:ibb:1' block-size='128' sid='coucou' stanza='fdsq'/>".parse().unwrap();
105        let error = Transport::try_from(elem).unwrap_err();
106        let message = match error {
107            Error::ParseError(string) => string,
108            _ => panic!(),
109        };
110        assert_eq!(message, "Invalid 'stanza' attribute.");
111    }
112}