diff --git a/src/room/canonical_alias.rs b/src/room/canonical_alias.rs index 7280650b..1e5530ee 100644 --- a/src/room/canonical_alias.rs +++ b/src/room/canonical_alias.rs @@ -147,6 +147,39 @@ impl_state_event!( EventType::RoomCanonicalAlias ); +impl FromStr for CanonicalAliasEventContent { + 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 { alias: raw.alias }) + } +} + +impl<'a> TryFrom<&'a str> for CanonicalAliasEventContent { + 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) + } +} + mod raw { use super::*; diff --git a/src/room/name.rs b/src/room/name.rs index e8181364..3c1019c8 100644 --- a/src/room/name.rs +++ b/src/room/name.rs @@ -163,6 +163,39 @@ impl NameEventContent { } } +impl FromStr for NameEventContent { + 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 { name: raw.name }) + } +} + +impl<'a> TryFrom<&'a str> for NameEventContent { + 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) + } +} + mod raw { use super::*; diff --git a/src/room/power_levels.rs b/src/room/power_levels.rs index 19c66716..a64d993d 100644 --- a/src/room/power_levels.rs +++ b/src/room/power_levels.rs @@ -202,6 +202,50 @@ impl_state_event!( EventType::RoomPowerLevels ); +impl FromStr for PowerLevelsEventContent { + 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 { + ban: raw.ban, + events: raw.events, + events_default: raw.events_default, + invite: raw.invite, + kick: raw.kick, + redact: raw.redact, + state_default: raw.state_default, + users: raw.users, + users_default: raw.users_default, + notifications: raw.notifications, + }) + } +} + +impl<'a> TryFrom<&'a str> for PowerLevelsEventContent { + 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) + } +} + mod raw { use super::*; diff --git a/src/room/server_acl.rs b/src/room/server_acl.rs index e5e09a77..1f486552 100644 --- a/src/room/server_acl.rs +++ b/src/room/server_acl.rs @@ -133,61 +133,46 @@ impl Serialize for ServerAclEvent { } } -impl Event for ServerAclEvent { - /// The type of this event's `content` field. - type Content = ServerAclEventContent; +impl_state_event!( + ServerAclEvent, + ServerAclEventContent, + EventType::RoomServerAcl +); - /// The event's content. - fn content(&self) -> &Self::Content { - &self.content - } +impl FromStr for ServerAclEventContent { + type Err = InvalidEvent; - /// The type of the event. - fn event_type(&self) -> EventType { - EventType::RoomServerAcl + /// 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 { + allow_ip_literals: raw.allow_ip_literals, + allow: raw.allow, + deny: raw.deny, + }) } } -impl RoomEvent for ServerAclEvent { - /// The unique identifier for the event. - fn event_id(&self) -> &EventId { - &self.event_id - } +impl<'a> TryFrom<&'a str> for ServerAclEventContent { + type Error = InvalidEvent; - /// Timestamp (milliseconds since the UNIX epoch) on originating homeserver when this event was - /// sent. - fn origin_server_ts(&self) -> UInt { - self.origin_server_ts - } - - /// The unique identifier for the room associated with this event. - /// - /// This can be `None` if the event came from a context where there is - /// no ambiguity which room it belongs to, like a `/sync` response for example. - fn room_id(&self) -> Option<&RoomId> { - self.room_id.as_ref() - } - - /// The unique identifier for the user who sent this event. - fn sender(&self) -> &UserId { - &self.sender - } - - /// Additional key-value pairs not signed by the homeserver. - fn unsigned(&self) -> Option<&Value> { - self.unsigned.as_ref() - } -} - -impl StateEvent for ServerAclEvent { - /// The previous content for this state key, if any. - fn prev_content(&self) -> Option<&Self::Content> { - self.prev_content.as_ref() - } - - /// A key that determines which piece of room state the event represents. - fn state_key(&self) -> &str { - &self.state_key + /// Attempt to create `Self` from parsing a string of JSON data. + fn try_from(json: &'a str) -> Result { + FromStr::from_str(json) } }