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
15type Date = String;
16
17#[derive(Debug, Clone)]
18pub struct Idle {
19 pub since: Date,
20}
21
22impl TryFrom<Element> for Idle {
23 type Error = Error;
24
25 fn try_from(elem: Element) -> Result<Idle, Error> {
26 if !elem.is("idle", ns::IDLE) {
27 return Err(Error::ParseError("This is not an idle element."));
28 }
29 for _ in elem.children() {
30 return Err(Error::ParseError("Unknown child in idle element."));
31 }
32 let since = get_attr!(elem, "since", required);
33 Ok(Idle { since: since })
34 }
35}
36
37impl Into<Element> for Idle {
38 fn into(self) -> Element {
39 Element::builder("idle")
40 .ns(ns::IDLE)
41 .attr("since", self.since.clone())
42 .build()
43 }
44}
45
46#[cfg(test)]
47mod tests {
48 use super::*;
49
50 #[test]
51 fn test_simple() {
52 let elem: Element = "<idle xmlns='urn:xmpp:idle:1' since='2017-05-21T20:19:55+01:00'/>".parse().unwrap();
53 Idle::try_from(elem).unwrap();
54 }
55
56 #[test]
57 fn test_invalid_child() {
58 let elem: Element = "<idle xmlns='urn:xmpp:idle:1'><coucou/></idle>".parse().unwrap();
59 let error = Idle::try_from(elem).unwrap_err();
60 let message = match error {
61 Error::ParseError(string) => string,
62 _ => panic!(),
63 };
64 assert_eq!(message, "Unknown child in idle element.");
65 }
66
67 #[test]
68 fn test_invalid_id() {
69 let elem: Element = "<idle xmlns='urn:xmpp:idle:1'/>".parse().unwrap();
70 let error = Idle::try_from(elem).unwrap_err();
71 let message = match error {
72 Error::ParseError(string) => string,
73 _ => panic!(),
74 };
75 assert_eq!(message, "Required attribute 'since' missing.");
76 }
77
78 #[test]
79 fn test_serialise() {
80 let elem: Element = "<idle xmlns='urn:xmpp:idle:1' since='2017-05-21T20:19:55+01:00'/>".parse().unwrap();
81 let idle = Idle { since: Date::from("2017-05-21T20:19:55+01:00") };
82 let elem2 = idle.into();
83 assert_eq!(elem, elem2);
84 }
85}