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
15#[derive(Debug, Clone)]
16pub enum ChatState {
17 Active,
18 Composing,
19 Gone,
20 Inactive,
21 Paused,
22}
23
24impl<'a> TryFrom<&'a Element> for ChatState {
25 type Error = Error;
26
27 fn try_from(elem: &'a Element) -> Result<ChatState, Error> {
28 for _ in elem.children() {
29 return Err(Error::ParseError("Unknown child in chatstate element."));
30 }
31 if elem.is("active", ns::CHATSTATES) {
32 Ok(ChatState::Active)
33 } else if elem.is("composing", ns::CHATSTATES) {
34 Ok(ChatState::Composing)
35 } else if elem.is("gone", ns::CHATSTATES) {
36 Ok(ChatState::Gone)
37 } else if elem.is("inactive", ns::CHATSTATES) {
38 Ok(ChatState::Inactive)
39 } else if elem.is("paused", ns::CHATSTATES) {
40 Ok(ChatState::Paused)
41 } else {
42 Err(Error::ParseError("This is not a chatstate element."))
43 }
44 }
45}
46
47impl<'a> Into<Element> for &'a ChatState {
48 fn into(self) -> Element {
49 Element::builder(match *self {
50 ChatState::Active => "active",
51 ChatState::Composing => "composing",
52 ChatState::Gone => "gone",
53 ChatState::Inactive => "inactive",
54 ChatState::Paused => "paused",
55 }).ns(ns::CHATSTATES)
56 .build()
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63
64 #[test]
65 fn test_simple() {
66 let elem: Element = "<active xmlns='http://jabber.org/protocol/chatstates'/>".parse().unwrap();
67 ChatState::try_from(&elem).unwrap();
68 }
69
70 #[test]
71 fn test_invalid() {
72 let elem: Element = "<coucou xmlns='http://jabber.org/protocol/chatstates'/>".parse().unwrap();
73 let error = ChatState::try_from(&elem).unwrap_err();
74 let message = match error {
75 Error::ParseError(string) => string,
76 _ => panic!(),
77 };
78 assert_eq!(message, "This is not a chatstate element.");
79 }
80
81 #[test]
82 fn test_invalid_child() {
83 let elem: Element = "<gone xmlns='http://jabber.org/protocol/chatstates'><coucou/></gone>".parse().unwrap();
84 let error = ChatState::try_from(&elem).unwrap_err();
85 let message = match error {
86 Error::ParseError(string) => string,
87 _ => panic!(),
88 };
89 assert_eq!(message, "Unknown child in chatstate element.");
90 }
91
92 #[test]
93 #[ignore]
94 fn test_invalid_attribute() {
95 let elem: Element = "<inactive xmlns='http://jabber.org/protocol/chatstates' coucou=''/>".parse().unwrap();
96 let error = ChatState::try_from(&elem).unwrap_err();
97 let message = match error {
98 Error::ParseError(string) => string,
99 _ => panic!(),
100 };
101 assert_eq!(message, "Unknown attribute in chatstate element.");
102 }
103
104 #[test]
105 fn test_serialise() {
106 let chatstate = ChatState::Active;
107 let elem: Element = (&chatstate).into();
108 assert!(elem.is("active", ns::CHATSTATES));
109 }
110}