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