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