diff --git a/ruma-events-macros/src/gen.rs b/ruma-events-macros/src/gen.rs index 6aed837c..b98058f5 100644 --- a/ruma-events-macros/src/gen.rs +++ b/ruma-events-macros/src/gen.rs @@ -166,7 +166,7 @@ impl ToTokens for RumaEvent { match &self.content { Content::Struct(_) => { quote_spanned! {span=> - content: crate::from_raw(raw.content), + content: crate::FromRaw::from_raw(raw.content), } } Content::Typedef(_) => { @@ -179,7 +179,7 @@ impl ToTokens for RumaEvent { match &self.content { Content::Struct(_) => { quote_spanned! {span=> - prev_content: raw.prev_content.map(crate::from_raw), + prev_content: raw.prev_content.map(crate::FromRaw::from_raw), } } Content::Typedef(_) => { @@ -327,16 +327,15 @@ impl ToTokens for RumaEvent { } quote! { - impl crate::TryFromRaw for #content_name { + impl crate::FromRaw for #content_name { type Raw = raw::#content_name; - type Err = crate::Void; - fn try_from_raw( + fn from_raw( raw: raw::#content_name - ) -> Result { - Ok(Self { + ) -> Self { + Self { #(#content_field_values)* - }) + } } } } @@ -353,14 +352,13 @@ impl ToTokens for RumaEvent { #content - impl crate::TryFromRaw for #name { + impl crate::FromRaw for #name { type Raw = raw::#name; - type Err = crate::Void; - fn try_from_raw(raw: raw::#name) -> Result { - Ok(Self { + fn from_raw(raw: raw::#name) -> Self { + Self { #(#try_from_field_values)* - }) + } } } diff --git a/ruma-events-macros/tests/ruma_events_macros.rs b/ruma-events-macros/tests/ruma_events_macros.rs index 3a9e0fe4..40af5588 100644 --- a/ruma-events-macros/tests/ruma_events_macros.rs +++ b/ruma-events-macros/tests/ruma_events_macros.rs @@ -105,6 +105,15 @@ impl EventResult { } } +/// Marks types that can be deserialized as EventResult (and don't need fallible conversion +/// from their raw type) +pub trait FromRaw: Sized { + /// The raw form of this event that deserialization falls back to if deserializing `Self` fails. + type Raw: DeserializeOwned; + + fn from_raw(_: Self::Raw) -> Self; +} + pub trait TryFromRaw { /// The raw form of this event that deserialization falls back to if deserializing `Self` fails. type Raw; @@ -113,13 +122,12 @@ pub trait TryFromRaw { fn try_from_raw(_: Self::Raw) -> Result; } -fn from_raw(raw: T::Raw) -> T -where - T: TryFromRaw, -{ - match T::try_from_raw(raw) { - Ok(c) => c, - Err((void, _)) => match void {}, +impl TryFromRaw for T { + type Raw = ::Raw; + type Err = Void; + + fn try_from_raw(raw: Self::Raw) -> Result { + Ok(Self::from_raw(raw)) } } diff --git a/src/collections/all.rs b/src/collections/all.rs index f3be59d1..d51bcabd 100644 --- a/src/collections/all.rs +++ b/src/collections/all.rs @@ -336,7 +336,7 @@ pub enum StateEvent { impl TryFromRaw for Event { type Raw = raw::Event; - type Err = Void; + type Err = String; fn try_from_raw(raw: raw::Event) -> Result { unimplemented!() @@ -345,7 +345,7 @@ impl TryFromRaw for Event { impl TryFromRaw for RoomEvent { type Raw = raw::RoomEvent; - type Err = Void; + type Err = String; fn try_from_raw(raw: raw::RoomEvent) -> Result { unimplemented!() diff --git a/src/ignored_user_list.rs b/src/ignored_user_list.rs index af7482dc..341aa3ec 100644 --- a/src/ignored_user_list.rs +++ b/src/ignored_user_list.rs @@ -3,7 +3,7 @@ use ruma_identifiers::UserId; use serde::{ser::SerializeStruct, Deserialize, Serialize, Serializer}; -use crate::{vec_as_map_of_empty, Event as _, EventType, TryFromRaw, Void}; +use crate::{vec_as_map_of_empty, Event as _, EventType, FromRaw}; /// A list of users to ignore. #[derive(Clone, Debug, PartialEq)] @@ -12,14 +12,13 @@ pub struct IgnoredUserListEvent { pub content: IgnoredUserListEventContent, } -impl TryFromRaw for IgnoredUserListEvent { +impl FromRaw for IgnoredUserListEvent { type Raw = raw::IgnoredUserListEvent; - type Err = Void; - fn try_from_raw(raw: raw::IgnoredUserListEvent) -> Result { - Ok(Self { - content: crate::from_raw(raw.content), - }) + fn from_raw(raw: raw::IgnoredUserListEvent) -> Self { + Self { + content: FromRaw::from_raw(raw.content), + } } } @@ -44,14 +43,13 @@ pub struct IgnoredUserListEventContent { pub ignored_users: Vec, } -impl TryFromRaw for IgnoredUserListEventContent { +impl FromRaw for IgnoredUserListEventContent { type Raw = raw::IgnoredUserListEventContent; - type Err = Void; - fn try_from_raw(raw: raw::IgnoredUserListEventContent) -> Result { - Ok(Self { + fn from_raw(raw: raw::IgnoredUserListEventContent) -> Self { + Self { ignored_users: raw.ignored_users, - }) + } } } diff --git a/src/lib.rs b/src/lib.rs index fdefbbed..0178adb9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -245,6 +245,15 @@ impl Display for InvalidInput { impl Error for InvalidInput {} +/// Marks types that can be deserialized as EventResult (and don't need fallible conversion +/// from their raw type) +pub trait FromRaw: Sized { + /// The raw form of this event that deserialization falls back to if deserializing `Self` fails. + type Raw: DeserializeOwned; + + fn from_raw(_: Self::Raw) -> Self; +} + /// Marks types that can be deserialized as EventResult pub trait TryFromRaw: Sized { /// The raw form of this event that deserialization falls back to if deserializing `Self` fails. @@ -254,6 +263,15 @@ pub trait TryFromRaw: Sized { fn try_from_raw(_: Self::Raw) -> Result; } +impl TryFromRaw for T { + type Raw = ::Raw; + type Err = Void; + + fn try_from_raw(raw: Self::Raw) -> Result { + Ok(Self::from_raw(raw)) + } +} + // TODO: Replace with ! once that is stable /// An empty type #[derive(Debug)] @@ -265,16 +283,6 @@ impl From for String { } } -fn from_raw(raw: T::Raw) -> T -where - T: TryFromRaw, -{ - match T::try_from_raw(raw) { - Ok(c) => c, - Err((void, _)) => match void {}, - } -} - /// The result of deserializing an event, which may or may not be valid. /// /// When data is successfully deserialized and validated, this structure will contain the diff --git a/src/room/canonical_alias.rs b/src/room/canonical_alias.rs index 8e6ea1e4..02ea676a 100644 --- a/src/room/canonical_alias.rs +++ b/src/room/canonical_alias.rs @@ -5,7 +5,7 @@ use ruma_identifiers::{EventId, RoomAliasId, RoomId, UserId}; use serde::{ser::SerializeStruct, Deserialize, Serialize, Serializer}; use serde_json::Value; -use crate::{empty_string_as_none, Event, EventType, TryFromRaw, Void}; +use crate::{empty_string_as_none, Event, EventType, FromRaw}; /// Informs the room as to which alias is the canonical one. #[derive(Clone, Debug, PartialEq)] @@ -45,30 +45,28 @@ pub struct CanonicalAliasEventContent { pub alias: Option, } -impl TryFromRaw for CanonicalAliasEvent { +impl FromRaw for CanonicalAliasEvent { type Raw = raw::CanonicalAliasEvent; - type Err = Void; - fn try_from_raw(raw: raw::CanonicalAliasEvent) -> Result { - Ok(Self { - content: crate::from_raw(raw.content), + fn from_raw(raw: raw::CanonicalAliasEvent) -> Self { + Self { + content: FromRaw::from_raw(raw.content), event_id: raw.event_id, origin_server_ts: raw.origin_server_ts, - prev_content: raw.prev_content.map(crate::from_raw), + prev_content: raw.prev_content.map(FromRaw::from_raw), room_id: raw.room_id, sender: raw.sender, state_key: raw.state_key, unsigned: raw.unsigned, - }) + } } } -impl TryFromRaw for CanonicalAliasEventContent { +impl FromRaw for CanonicalAliasEventContent { type Raw = raw::CanonicalAliasEventContent; - type Err = Void; - fn try_from_raw(raw: raw::CanonicalAliasEventContent) -> Result { - Ok(Self { alias: raw.alias }) + fn from_raw(raw: raw::CanonicalAliasEventContent) -> Self { + Self { alias: raw.alias } } } diff --git a/src/room/encrypted.rs b/src/room/encrypted.rs index bd4d07db..5dd26131 100644 --- a/src/room/encrypted.rs +++ b/src/room/encrypted.rs @@ -5,7 +5,7 @@ use ruma_identifiers::{DeviceId, EventId, RoomId, UserId}; use serde::{de::Error, ser::SerializeStruct, Deserialize, Deserializer, Serialize, Serializer}; use serde_json::{from_value, Value}; -use crate::{Algorithm, Event, EventType, TryFromRaw, Void}; +use crate::{Algorithm, Event, EventType, FromRaw}; /// This event type is used when sending encrypted events. /// @@ -48,36 +48,34 @@ pub enum EncryptedEventContent { __Nonexhaustive, } -impl TryFromRaw for EncryptedEvent { +impl FromRaw for EncryptedEvent { type Raw = raw::EncryptedEvent; - type Err = Void; - fn try_from_raw(raw: raw::EncryptedEvent) -> Result { - Ok(Self { - content: crate::from_raw(raw.content), + fn from_raw(raw: raw::EncryptedEvent) -> Self { + Self { + content: FromRaw::from_raw(raw.content), event_id: raw.event_id, origin_server_ts: raw.origin_server_ts, room_id: raw.room_id, sender: raw.sender, unsigned: raw.unsigned, - }) + } } } -impl TryFromRaw for EncryptedEventContent { +impl FromRaw for EncryptedEventContent { type Raw = raw::EncryptedEventContent; - type Err = Void; - fn try_from_raw(raw: raw::EncryptedEventContent) -> Result { + fn from_raw(raw: raw::EncryptedEventContent) -> Self { use raw::EncryptedEventContent::*; - Ok(match raw { + match raw { OlmV1Curve25519AesSha2(content) => Self::OlmV1Curve25519AesSha2(content), MegolmV1AesSha2(content) => Self::MegolmV1AesSha2(content), __Nonexhaustive => { unreachable!("__Nonexhaustive variant should be impossible to obtain.") } - }) + } } } diff --git a/src/room/message.rs b/src/room/message.rs index b057e8ad..f32844be 100644 --- a/src/room/message.rs +++ b/src/room/message.rs @@ -10,7 +10,7 @@ use serde::{ use serde_json::{from_value, Value}; use super::{EncryptedFile, ImageInfo, ThumbnailInfo}; -use crate::{Event, EventType, TryFromRaw, Void}; +use crate::{Event, EventType, FromRaw}; pub mod feedback; @@ -74,30 +74,28 @@ pub enum MessageEventContent { __Nonexhaustive, } -impl TryFromRaw for MessageEvent { +impl FromRaw for MessageEvent { type Raw = raw::MessageEvent; - type Err = Void; - fn try_from_raw(raw: raw::MessageEvent) -> Result { - Ok(Self { - content: crate::from_raw(raw.content), + fn from_raw(raw: raw::MessageEvent) -> Self { + Self { + content: FromRaw::from_raw(raw.content), event_id: raw.event_id, origin_server_ts: raw.origin_server_ts, room_id: raw.room_id, sender: raw.sender, unsigned: raw.unsigned, - }) + } } } -impl TryFromRaw for MessageEventContent { +impl FromRaw for MessageEventContent { type Raw = raw::MessageEventContent; - type Err = Void; - fn try_from_raw(raw: raw::MessageEventContent) -> Result { + fn from_raw(raw: raw::MessageEventContent) -> Self { use raw::MessageEventContent::*; - Ok(match raw { + match raw { Audio(content) => Self::Audio(content), Emote(content) => Self::Emote(content), File(content) => Self::File(content), @@ -110,7 +108,7 @@ impl TryFromRaw for MessageEventContent { __Nonexhaustive => { unreachable!("It should be impossible to obtain a __Nonexhaustive variant.") } - }) + } } } diff --git a/src/room/name.rs b/src/room/name.rs index f7d49a61..a888a1b9 100644 --- a/src/room/name.rs +++ b/src/room/name.rs @@ -5,7 +5,7 @@ use ruma_identifiers::{EventId, RoomId, UserId}; use serde::{ser::SerializeStruct, Deserialize, Serialize, Serializer}; use serde_json::Value; -use crate::{empty_string_as_none, Event as _, EventType, InvalidInput, TryFromRaw, Void}; +use crate::{empty_string_as_none, Event as _, EventType, FromRaw, InvalidInput}; /// A human-friendly room name designed to be displayed to the end-user. #[derive(Clone, Debug, PartialEq)] @@ -43,30 +43,28 @@ pub struct NameEventContent { pub(crate) name: Option, } -impl TryFromRaw for NameEvent { +impl FromRaw for NameEvent { type Raw = raw::NameEvent; - type Err = Void; - fn try_from_raw(raw: raw::NameEvent) -> Result { - Ok(Self { - content: crate::from_raw(raw.content), + fn from_raw(raw: raw::NameEvent) -> Self { + Self { + content: FromRaw::from_raw(raw.content), event_id: raw.event_id, origin_server_ts: raw.origin_server_ts, - prev_content: raw.prev_content.map(crate::from_raw), + prev_content: raw.prev_content.map(FromRaw::from_raw), room_id: raw.room_id, sender: raw.sender, state_key: raw.state_key, unsigned: raw.unsigned, - }) + } } } -impl TryFromRaw for NameEventContent { +impl FromRaw for NameEventContent { type Raw = raw::NameEventContent; - type Err = Void; - fn try_from_raw(raw: raw::NameEventContent) -> Result { - Ok(Self { name: raw.name }) + fn from_raw(raw: raw::NameEventContent) -> Self { + Self { name: raw.name } } } diff --git a/src/room/power_levels.rs b/src/room/power_levels.rs index 69fbfd7b..cb6fe15d 100644 --- a/src/room/power_levels.rs +++ b/src/room/power_levels.rs @@ -7,7 +7,7 @@ use ruma_identifiers::{EventId, RoomId, UserId}; use serde::{ser::SerializeStruct, Deserialize, Serialize, Serializer}; use serde_json::Value; -use crate::{Event as _, EventType, TryFromRaw, Void}; +use crate::{Event as _, EventType, FromRaw}; /// Defines the power levels (privileges) of users in the room. #[derive(Clone, Debug, PartialEq)] @@ -85,30 +85,28 @@ pub struct PowerLevelsEventContent { pub notifications: NotificationPowerLevels, } -impl TryFromRaw for PowerLevelsEvent { +impl FromRaw for PowerLevelsEvent { type Raw = raw::PowerLevelsEvent; - type Err = Void; - fn try_from_raw(raw: raw::PowerLevelsEvent) -> Result { - Ok(Self { - content: crate::from_raw(raw.content), + fn from_raw(raw: raw::PowerLevelsEvent) -> Self { + Self { + content: FromRaw::from_raw(raw.content), event_id: raw.event_id, origin_server_ts: raw.origin_server_ts, - prev_content: raw.prev_content.map(crate::from_raw), + prev_content: raw.prev_content.map(FromRaw::from_raw), room_id: raw.room_id, unsigned: raw.unsigned, sender: raw.sender, state_key: raw.state_key, - }) + } } } -impl TryFromRaw for PowerLevelsEventContent { +impl FromRaw for PowerLevelsEventContent { type Raw = raw::PowerLevelsEventContent; - type Err = Void; - fn try_from_raw(raw: raw::PowerLevelsEventContent) -> Result { - Ok(Self { + fn from_raw(raw: raw::PowerLevelsEventContent) -> Self { + Self { ban: raw.ban, events: raw.events, events_default: raw.events_default, @@ -119,7 +117,7 @@ impl TryFromRaw for PowerLevelsEventContent { users: raw.users, users_default: raw.users_default, notifications: raw.notifications, - }) + } } } diff --git a/src/room/server_acl.rs b/src/room/server_acl.rs index a430165b..4869c562 100644 --- a/src/room/server_acl.rs +++ b/src/room/server_acl.rs @@ -5,7 +5,7 @@ use ruma_identifiers::{EventId, RoomId, UserId}; use serde::{ser::SerializeStruct, Deserialize, Serialize, Serializer}; use serde_json::Value; -use crate::{default_true, Event as _, EventType, TryFromRaw, Void}; +use crate::{default_true, Event as _, EventType, FromRaw}; /// An event to indicate which servers are permitted to participate in the room. #[derive(Clone, Debug, PartialEq)] @@ -65,34 +65,32 @@ pub struct ServerAclEventContent { pub deny: Vec, } -impl TryFromRaw for ServerAclEvent { +impl FromRaw for ServerAclEvent { type Raw = raw::ServerAclEvent; - type Err = Void; - fn try_from_raw(raw: raw::ServerAclEvent) -> Result { - Ok(Self { - content: crate::from_raw(raw.content), + fn from_raw(raw: raw::ServerAclEvent) -> Self { + Self { + content: FromRaw::from_raw(raw.content), event_id: raw.event_id, origin_server_ts: raw.origin_server_ts, - prev_content: raw.prev_content.map(crate::from_raw), + prev_content: raw.prev_content.map(FromRaw::from_raw), room_id: raw.room_id, sender: raw.sender, state_key: raw.state_key, unsigned: raw.unsigned, - }) + } } } -impl TryFromRaw for ServerAclEventContent { +impl FromRaw for ServerAclEventContent { type Raw = raw::ServerAclEventContent; - type Err = Void; - fn try_from_raw(raw: raw::ServerAclEventContent) -> Result { - Ok(Self { + fn from_raw(raw: raw::ServerAclEventContent) -> Self { + Self { allow_ip_literals: raw.allow_ip_literals, allow: raw.allow, deny: raw.deny, - }) + } } }