From bce1e914692f24e0f847d27e628ff144103f6bb5 Mon Sep 17 00:00:00 2001 From: Jimmy Cuadra Date: Fri, 19 Jul 2019 14:08:34 -0700 Subject: [PATCH] Add FromStr and TryFrom impls for m.ignored_user_list types. --- src/ignored_user_list.rs | 80 ++++++++++++++++++++++++++++++++-------- 1 file changed, 65 insertions(+), 15 deletions(-) diff --git a/src/ignored_user_list.rs b/src/ignored_user_list.rs index e4cbc8ca..449c0917 100644 --- a/src/ignored_user_list.rs +++ b/src/ignored_user_list.rs @@ -1,11 +1,11 @@ //! Types for the *m.ignored_user_list* event. -use std::collections::HashMap; +use std::{collections::HashMap, convert::TryFrom, str::FromStr}; use ruma_identifiers::UserId; use serde::{ser::SerializeStruct, Deserialize, Serialize, Serializer}; -use crate::{Empty, Event, EventType, InvalidEvent}; +use crate::{Empty, Event, EventType, InnerInvalidEvent, InvalidEvent}; /// A list of users to ignore. #[derive(Clone, Debug, PartialEq)] @@ -21,10 +21,25 @@ pub struct IgnoredUserListEventContent { pub ignored_users: Vec, } -impl IgnoredUserListEvent { +impl FromStr for IgnoredUserListEvent { + type Err = InvalidEvent; + /// Attempt to create `Self` from parsing a string of JSON data. - pub fn from_str(json: &str) -> Result { - let raw = serde_json::from_str::(json)?; + fn from_str(json: &str) -> Result { + let raw = match serde_json::from_str::(json) { + Ok(raw) => raw, + Err(error) => match serde_json::from_str::(json) { + Ok(value) => { + return Err(InvalidEvent(InnerInvalidEvent::Validation { + json: value, + message: error.to_string(), + })); + } + Err(error) => { + return Err(InvalidEvent(InnerInvalidEvent::Deserialization { error })); + } + }, + }; Ok(Self { content: IgnoredUserListEventContent { @@ -34,6 +49,15 @@ impl IgnoredUserListEvent { } } +impl<'a> TryFrom<&'a str> for IgnoredUserListEvent { + type Error = InvalidEvent; + + /// Attempt to create `Self` from parsing a string of JSON data. + fn try_from(json: &'a str) -> Result { + FromStr::from_str(json) + } +} + impl Serialize for IgnoredUserListEvent { fn serialize(&self, serializer: S) -> Result where @@ -48,18 +72,44 @@ impl Serialize for IgnoredUserListEvent { } } -impl crate::Event for IgnoredUserListEvent { - /// The type of this event's `content` field. - type Content = IgnoredUserListEventContent; +impl_event!( + IgnoredUserListEvent, + IgnoredUserListEventContent, + EventType::IgnoredUserList +); - /// The event's content. - fn content(&self) -> &Self::Content { - &self.content +impl FromStr for IgnoredUserListEventContent { + type Err = InvalidEvent; + + /// Attempt to create `Self` from parsing a string of JSON data. + fn from_str(json: &str) -> Result { + let raw = match serde_json::from_str::(json) { + Ok(raw) => raw, + Err(error) => match serde_json::from_str::(json) { + Ok(value) => { + return Err(InvalidEvent(InnerInvalidEvent::Validation { + json: value, + message: error.to_string(), + })); + } + Err(error) => { + return Err(InvalidEvent(InnerInvalidEvent::Deserialization { error })); + } + }, + }; + + Ok(Self { + ignored_users: raw.ignored_users.keys().cloned().collect(), + }) } +} - /// The type of the event. - fn event_type(&self) -> EventType { - EventType::IgnoredUserList +impl<'a> TryFrom<&'a str> for IgnoredUserListEventContent { + type Error = InvalidEvent; + + /// Attempt to create `Self` from parsing a string of JSON data. + fn try_from(json: &'a str) -> Result { + FromStr::from_str(json) } } @@ -124,7 +174,7 @@ mod tests { fn deserialization() { let json = r#"{"content":{"ignored_users":{"@carl:example.com":{}}},"type":"m.ignored_user_list"}"#; - let actual = IgnoredUserListEvent::from_str(json).unwrap(); + let actual: IgnoredUserListEvent = json.parse().unwrap(); let expected = IgnoredUserListEvent { content: IgnoredUserListEventContent {