delay.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;
 12use jid::Jid;
 13
 14use ns;
 15
 16#[derive(Debug, Clone)]
 17pub struct Delay {
 18    pub from: Option<Jid>,
 19    pub stamp: String,
 20    pub data: Option<String>,
 21}
 22
 23impl TryFrom<Element> for Delay {
 24    type Error = Error;
 25
 26    fn try_from(elem: Element) -> Result<Delay, Error> {
 27        if !elem.is("delay", ns::DELAY) {
 28            return Err(Error::ParseError("This is not a delay element."));
 29        }
 30        for _ in elem.children() {
 31            return Err(Error::ParseError("Unknown child in delay element."));
 32        }
 33        let from = get_attr!(elem, "from", optional);
 34        let stamp = get_attr!(elem, "stamp", required);
 35        let data = match elem.text().as_ref() {
 36            "" => None,
 37            text => Some(text.to_owned()),
 38        };
 39        Ok(Delay {
 40            from: from,
 41            stamp: stamp,
 42            data: data,
 43        })
 44    }
 45}
 46
 47impl Into<Element> for Delay {
 48    fn into(self) -> Element {
 49        Element::builder("delay")
 50                .ns(ns::DELAY)
 51                .attr("from", self.from.clone().and_then(|value| Some(String::from(value))))
 52                .attr("stamp", self.stamp.clone())
 53                .append(self.data.clone())
 54                .build()
 55    }
 56}
 57
 58#[cfg(test)]
 59mod tests {
 60    use std::str::FromStr;
 61    use super::*;
 62
 63    #[test]
 64    fn test_simple() {
 65        let elem: Element = "<delay xmlns='urn:xmpp:delay' from='capulet.com' stamp='2002-09-10T23:08:25Z'/>".parse().unwrap();
 66        let delay = Delay::try_from(elem).unwrap();
 67        assert_eq!(delay.from, Some(Jid::from_str("capulet.com").unwrap()));
 68        assert_eq!(delay.stamp, "2002-09-10T23:08:25Z");
 69        assert_eq!(delay.data, None);
 70    }
 71
 72    #[test]
 73    fn test_unknown() {
 74        let elem: Element = "<replace xmlns='urn:xmpp:message-correct:0'/>".parse().unwrap();
 75        let error = Delay::try_from(elem).unwrap_err();
 76        let message = match error {
 77            Error::ParseError(string) => string,
 78            _ => panic!(),
 79        };
 80        assert_eq!(message, "This is not a delay element.");
 81    }
 82
 83    #[test]
 84    fn test_invalid_child() {
 85        let elem: Element = "<delay xmlns='urn:xmpp:delay'><coucou/></delay>".parse().unwrap();
 86        let error = Delay::try_from(elem).unwrap_err();
 87        let message = match error {
 88            Error::ParseError(string) => string,
 89            _ => panic!(),
 90        };
 91        assert_eq!(message, "Unknown child in delay element.");
 92    }
 93
 94    #[test]
 95    fn test_serialise() {
 96        let elem: Element = "<delay xmlns='urn:xmpp:delay' stamp='2002-09-10T23:08:25Z'/>".parse().unwrap();
 97        let delay = Delay {
 98            from: None,
 99            stamp: "2002-09-10T23:08:25Z".to_owned(),
100            data: None,
101        };
102        let elem2 = delay.into();
103        assert_eq!(elem, elem2);
104    }
105
106    #[test]
107    fn test_serialise_data() {
108        let elem: Element = "<delay xmlns='urn:xmpp:delay' from='juliet@example.org' stamp='2002-09-10T23:08:25Z'>Reason</delay>".parse().unwrap();
109        let delay = Delay {
110            from: Some(Jid::from_str("juliet@example.org").unwrap()),
111            stamp: "2002-09-10T23:08:25Z".to_owned(),
112            data: Some(String::from("Reason")),
113        };
114        let elem2 = delay.into();
115        assert_eq!(elem, elem2);
116    }
117}