chatstates: Switch to Into/TryFrom.

Emmanuel Gil Peyrot created

Change summary

src/chatstates.rs | 75 ++++++++++++++++++++++++++----------------------
src/message.rs    |  8 ++--
2 files changed, 44 insertions(+), 39 deletions(-)

Detailed changes

src/chatstates.rs 🔗

@@ -4,6 +4,8 @@
 // License, v. 2.0. If a copy of the MPL was not distributed with this
 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+use std::convert::TryFrom;
+
 use minidom::Element;
 
 use error::Error;
@@ -19,53 +21,56 @@ pub enum ChatState {
     Paused,
 }
 
-pub fn parse_chatstate(root: &Element) -> Result<ChatState, Error> {
-    for _ in root.children() {
-        return Err(Error::ParseError("Unknown child in chatstate element."));
-    }
-    if root.is("active", ns::CHATSTATES) {
-        Ok(ChatState::Active)
-    } else if root.is("composing", ns::CHATSTATES) {
-        Ok(ChatState::Composing)
-    } else if root.is("gone", ns::CHATSTATES) {
-        Ok(ChatState::Gone)
-    } else if root.is("inactive", ns::CHATSTATES) {
-        Ok(ChatState::Inactive)
-    } else if root.is("paused", ns::CHATSTATES) {
-        Ok(ChatState::Paused)
-    } else {
-        Err(Error::ParseError("This is not a chatstate element."))
+impl<'a> TryFrom<&'a Element> for ChatState {
+    type Error = Error;
+
+    fn try_from(elem: &'a Element) -> Result<ChatState, Error> {
+        for _ in elem.children() {
+            return Err(Error::ParseError("Unknown child in chatstate element."));
+        }
+        if elem.is("active", ns::CHATSTATES) {
+            Ok(ChatState::Active)
+        } else if elem.is("composing", ns::CHATSTATES) {
+            Ok(ChatState::Composing)
+        } else if elem.is("gone", ns::CHATSTATES) {
+            Ok(ChatState::Gone)
+        } else if elem.is("inactive", ns::CHATSTATES) {
+            Ok(ChatState::Inactive)
+        } else if elem.is("paused", ns::CHATSTATES) {
+            Ok(ChatState::Paused)
+        } else {
+            Err(Error::ParseError("This is not a chatstate element."))
+        }
     }
 }
 
-pub fn serialise(chatstate: &ChatState) -> Element {
-    Element::builder(match *chatstate {
-        ChatState::Active => "active",
-        ChatState::Composing => "composing",
-        ChatState::Gone => "gone",
-        ChatState::Inactive => "inactive",
-        ChatState::Paused => "paused",
-    }).ns(ns::CHATSTATES)
-      .build()
+impl<'a> Into<Element> for &'a ChatState {
+    fn into(self) -> Element {
+        Element::builder(match *self {
+            ChatState::Active => "active",
+            ChatState::Composing => "composing",
+            ChatState::Gone => "gone",
+            ChatState::Inactive => "inactive",
+            ChatState::Paused => "paused",
+        }).ns(ns::CHATSTATES)
+          .build()
+    }
 }
 
 #[cfg(test)]
 mod tests {
-    use minidom::Element;
-    use error::Error;
-    use chatstates;
-    use ns;
+    use super::*;
 
     #[test]
     fn test_simple() {
         let elem: Element = "<active xmlns='http://jabber.org/protocol/chatstates'/>".parse().unwrap();
-        chatstates::parse_chatstate(&elem).unwrap();
+        ChatState::try_from(&elem).unwrap();
     }
 
     #[test]
     fn test_invalid() {
         let elem: Element = "<coucou xmlns='http://jabber.org/protocol/chatstates'/>".parse().unwrap();
-        let error = chatstates::parse_chatstate(&elem).unwrap_err();
+        let error = ChatState::try_from(&elem).unwrap_err();
         let message = match error {
             Error::ParseError(string) => string,
             _ => panic!(),
@@ -76,7 +81,7 @@ mod tests {
     #[test]
     fn test_invalid_child() {
         let elem: Element = "<gone xmlns='http://jabber.org/protocol/chatstates'><coucou/></gone>".parse().unwrap();
-        let error = chatstates::parse_chatstate(&elem).unwrap_err();
+        let error = ChatState::try_from(&elem).unwrap_err();
         let message = match error {
             Error::ParseError(string) => string,
             _ => panic!(),
@@ -88,7 +93,7 @@ mod tests {
     #[ignore]
     fn test_invalid_attribute() {
         let elem: Element = "<inactive xmlns='http://jabber.org/protocol/chatstates' coucou=''/>".parse().unwrap();
-        let error = chatstates::parse_chatstate(&elem).unwrap_err();
+        let error = ChatState::try_from(&elem).unwrap_err();
         let message = match error {
             Error::ParseError(string) => string,
             _ => panic!(),
@@ -98,8 +103,8 @@ mod tests {
 
     #[test]
     fn test_serialise() {
-        let chatstate = chatstates::ChatState::Active;
-        let elem = chatstates::serialise(&chatstate);
+        let chatstate = ChatState::Active;
+        let elem: Element = (&chatstate).into();
         assert!(elem.is("active", ns::CHATSTATES));
     }
 }

src/message.rs 🔗

@@ -17,7 +17,7 @@ use ns;
 
 use body;
 use stanza_error;
-use chatstates;
+use chatstates::ChatState;
 use receipts::Receipt;
 use delay;
 use attention::Attention;
@@ -29,7 +29,7 @@ use eme;
 pub enum MessagePayload {
     Body(body::Body),
     StanzaError(stanza_error::StanzaError),
-    ChatState(chatstates::ChatState),
+    ChatState(ChatState),
     Receipt(Receipt),
     Delay(delay::Delay),
     Attention(Attention),
@@ -115,7 +115,7 @@ pub fn parse_message(root: &Element) -> Result<Message, Error> {
             Some(MessagePayload::Body(body))
         } else if let Ok(stanza_error) = stanza_error::parse_stanza_error(elem) {
             Some(MessagePayload::StanzaError(stanza_error))
-        } else if let Ok(chatstate) = chatstates::parse_chatstate(elem) {
+        } else if let Ok(chatstate) = ChatState::try_from(elem) {
             Some(MessagePayload::ChatState(chatstate))
         } else if let Ok(receipt) = Receipt::try_from(elem) {
             Some(MessagePayload::Receipt(receipt))
@@ -149,7 +149,7 @@ pub fn serialise_payload(payload: &MessagePayload) -> Element {
         MessagePayload::Body(ref body) => body::serialise(body),
         MessagePayload::StanzaError(ref stanza_error) => stanza_error::serialise(stanza_error),
         MessagePayload::Attention(ref attention) => attention.into(),
-        MessagePayload::ChatState(ref chatstate) => chatstates::serialise(chatstate),
+        MessagePayload::ChatState(ref chatstate) => chatstate.into(),
         MessagePayload::Receipt(ref receipt) => receipt.into(),
         MessagePayload::Delay(ref delay) => delay::serialise(delay),
         MessagePayload::MessageCorrect(ref replace) => replace.into(),