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