message: Stop parsing the payloads automatically.

Emmanuel Gil Peyrot created

Change summary

src/message.rs | 106 +++++++++++++++++++++++++++------------------------
1 file changed, 56 insertions(+), 50 deletions(-)

Detailed changes

src/message.rs 🔗

@@ -38,6 +38,59 @@ pub enum MessagePayload {
     StanzaId(StanzaId),
 }
 
+impl<'a> TryFrom<&'a Element> for MessagePayload {
+    type Error = Error;
+
+    fn try_from(elem: &'a Element) -> Result<MessagePayload, Error> {
+        Ok(match (elem.name().as_ref(), elem.ns().unwrap().as_ref()) {
+            ("error", ns::JABBER_CLIENT) => MessagePayload::StanzaError(StanzaError::try_from(elem)?),
+
+            // XEP-0085
+            ("active", ns::CHATSTATES) => MessagePayload::ChatState(ChatState::try_from(elem)?),
+            ("inactive", ns::CHATSTATES) => MessagePayload::ChatState(ChatState::try_from(elem)?),
+            ("composing", ns::CHATSTATES) => MessagePayload::ChatState(ChatState::try_from(elem)?),
+            ("paused", ns::CHATSTATES) => MessagePayload::ChatState(ChatState::try_from(elem)?),
+            ("gone", ns::CHATSTATES) => MessagePayload::ChatState(ChatState::try_from(elem)?),
+
+            // XEP-0184
+            ("request", ns::RECEIPTS) => MessagePayload::Receipt(Receipt::try_from(elem)?),
+            ("received", ns::RECEIPTS) => MessagePayload::Receipt(Receipt::try_from(elem)?),
+
+            // XEP-0203
+            ("delay", ns::DELAY) => MessagePayload::Delay(Delay::try_from(elem)?),
+
+            // XEP-0224
+            ("attention", ns::ATTENTION) => MessagePayload::Attention(Attention::try_from(elem)?),
+
+            // XEP-0308
+            ("replace", ns::MESSAGE_CORRECT) => MessagePayload::MessageCorrect(Replace::try_from(elem)?),
+
+            // XEP-0359
+            ("stanza-id", ns::SID) => MessagePayload::StanzaId(StanzaId::try_from(elem)?),
+
+            // XEP-0380
+            ("encryption", ns::EME) => MessagePayload::ExplicitMessageEncryption(ExplicitMessageEncryption::try_from(elem)?),
+
+            _ => return Err(Error::ParseError("Unknown message payload."))
+        })
+    }
+}
+
+impl<'a> Into<Element> for &'a MessagePayload {
+    fn into(self) -> Element {
+        match *self {
+            MessagePayload::StanzaError(ref stanza_error) => stanza_error.into(),
+            MessagePayload::Attention(ref attention) => attention.into(),
+            MessagePayload::ChatState(ref chatstate) => chatstate.into(),
+            MessagePayload::Receipt(ref receipt) => receipt.into(),
+            MessagePayload::Delay(ref delay) => delay.into(),
+            MessagePayload::MessageCorrect(ref replace) => replace.into(),
+            MessagePayload::ExplicitMessageEncryption(ref eme) => eme.into(),
+            MessagePayload::StanzaId(ref stanza_id) => stanza_id.into(),
+        }
+    }
+}
+
 #[derive(Debug, Clone, PartialEq)]
 pub enum MessageType {
     Chat,
@@ -81,12 +134,6 @@ impl IntoAttributeValue for MessageType {
     }
 }
 
-#[derive(Debug, Clone)]
-pub enum MessagePayloadType {
-    XML(Element),
-    Parsed(MessagePayload),
-}
-
 type Lang = String;
 type Body = String;
 type Subject = String;
@@ -101,7 +148,7 @@ pub struct Message {
     pub bodies: BTreeMap<Lang, Body>,
     pub subjects: BTreeMap<Lang, Subject>,
     pub thread: Option<Thread>,
-    pub payloads: Vec<MessagePayloadType>,
+    pub payloads: Vec<Element>,
 }
 
 impl<'a> TryFrom<&'a Element> for Message {
@@ -151,29 +198,7 @@ impl<'a> TryFrom<&'a Element> for Message {
                 }
                 thread = Some(elem.text());
             } else {
-                let payload = if let Ok(stanza_error) = StanzaError::try_from(elem) {
-                    Some(MessagePayload::StanzaError(stanza_error))
-                } 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))
-                } else if let Ok(delay) = Delay::try_from(elem) {
-                    Some(MessagePayload::Delay(delay))
-                } else if let Ok(attention) = Attention::try_from(elem) {
-                    Some(MessagePayload::Attention(attention))
-                } else if let Ok(replace) = Replace::try_from(elem) {
-                    Some(MessagePayload::MessageCorrect(replace))
-                } else if let Ok(eme) = ExplicitMessageEncryption::try_from(elem) {
-                    Some(MessagePayload::ExplicitMessageEncryption(eme))
-                } else if let Ok(stanza_id) = StanzaId::try_from(elem) {
-                    Some(MessagePayload::StanzaId(stanza_id))
-                } else {
-                    None
-                };
-                payloads.push(match payload {
-                    Some(payload) => MessagePayloadType::Parsed(payload),
-                    None => MessagePayloadType::XML(elem.clone()),
-                });
+                payloads.push(elem.clone())
             }
         }
         Ok(Message {
@@ -189,21 +214,6 @@ impl<'a> TryFrom<&'a Element> for Message {
     }
 }
 
-impl<'a> Into<Element> for &'a MessagePayload {
-    fn into(self) -> Element {
-        match *self {
-            MessagePayload::StanzaError(ref stanza_error) => stanza_error.into(),
-            MessagePayload::Attention(ref attention) => attention.into(),
-            MessagePayload::ChatState(ref chatstate) => chatstate.into(),
-            MessagePayload::Receipt(ref receipt) => receipt.into(),
-            MessagePayload::Delay(ref delay) => delay.into(),
-            MessagePayload::MessageCorrect(ref replace) => replace.into(),
-            MessagePayload::ExplicitMessageEncryption(ref eme) => eme.into(),
-            MessagePayload::StanzaId(ref stanza_id) => stanza_id.into(),
-        }
-    }
-}
-
 impl<'a> Into<Element> for &'a Message {
     fn into(self) -> Element {
         let mut stanza = Element::builder("message")
@@ -236,11 +246,7 @@ impl<'a> Into<Element> for &'a Message {
                                                     .collect::<Vec<_>>())
                                  .build();
         for child in self.payloads.clone() {
-            let elem = match child {
-                MessagePayloadType::XML(elem) => elem,
-                MessagePayloadType::Parsed(payload) => (&payload).into(),
-            };
-            stanza.append_child(elem);
+            stanza.append_child(child);
         }
         stanza
     }