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