Introduce FromRaw in addition to TryFromRaw

This commit is contained in:
Jonas Platte 2019-10-15 20:26:30 +02:00
parent a6c34596d7
commit 09b8de5b6e
11 changed files with 118 additions and 118 deletions

View File

@ -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<Self, (Self::Err, Self::Raw)> {
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<Self, (Self::Err, Self::Raw)> {
Ok(Self {
fn from_raw(raw: raw::#name) -> Self {
Self {
#(#try_from_field_values)*
})
}
}
}

View File

@ -105,6 +105,15 @@ impl<T: TryFromRaw> EventResult<T> {
}
}
/// Marks types that can be deserialized as EventResult<Self> (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<Self, (Self::Err, Self::Raw)>;
}
fn from_raw<T>(raw: T::Raw) -> T
where
T: TryFromRaw<Err = Void>,
{
match T::try_from_raw(raw) {
Ok(c) => c,
Err((void, _)) => match void {},
impl<T: FromRaw> TryFromRaw for T {
type Raw = <T as FromRaw>::Raw;
type Err = Void;
fn try_from_raw(raw: Self::Raw) -> Result<Self, (Self::Err, Self::Raw)> {
Ok(Self::from_raw(raw))
}
}

View File

@ -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<Self, (Self::Err, Self::Raw)> {
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<Self, (Self::Err, Self::Raw)> {
unimplemented!()

View File

@ -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<Self, (Self::Err, Self::Raw)> {
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<UserId>,
}
impl TryFromRaw for IgnoredUserListEventContent {
impl FromRaw for IgnoredUserListEventContent {
type Raw = raw::IgnoredUserListEventContent;
type Err = Void;
fn try_from_raw(raw: raw::IgnoredUserListEventContent) -> Result<Self, (Self::Err, Self::Raw)> {
Ok(Self {
fn from_raw(raw: raw::IgnoredUserListEventContent) -> Self {
Self {
ignored_users: raw.ignored_users,
})
}
}
}

View File

@ -245,6 +245,15 @@ impl Display for InvalidInput {
impl Error for InvalidInput {}
/// Marks types that can be deserialized as EventResult<Self> (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<Self>
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<Self, (Self::Err, Self::Raw)>;
}
impl<T: FromRaw> TryFromRaw for T {
type Raw = <T as FromRaw>::Raw;
type Err = Void;
fn try_from_raw(raw: Self::Raw) -> Result<Self, (Self::Err, Self::Raw)> {
Ok(Self::from_raw(raw))
}
}
// TODO: Replace with ! once that is stable
/// An empty type
#[derive(Debug)]
@ -265,16 +283,6 @@ impl From<Void> for String {
}
}
fn from_raw<T>(raw: T::Raw) -> T
where
T: TryFromRaw<Err = Void>,
{
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

View File

@ -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<RoomAliasId>,
}
impl TryFromRaw for CanonicalAliasEvent {
impl FromRaw for CanonicalAliasEvent {
type Raw = raw::CanonicalAliasEvent;
type Err = Void;
fn try_from_raw(raw: raw::CanonicalAliasEvent) -> Result<Self, (Self::Err, Self::Raw)> {
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<Self, (Self::Err, Self::Raw)> {
Ok(Self { alias: raw.alias })
fn from_raw(raw: raw::CanonicalAliasEventContent) -> Self {
Self { alias: raw.alias }
}
}

View File

@ -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<Self, (Self::Err, Self::Raw)> {
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<Self, (Self::Err, Self::Raw)> {
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.")
}
})
}
}
}

View File

@ -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<Self, (Self::Err, Self::Raw)> {
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<Self, (Self::Err, Self::Raw)> {
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.")
}
})
}
}
}

View File

@ -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<String>,
}
impl TryFromRaw for NameEvent {
impl FromRaw for NameEvent {
type Raw = raw::NameEvent;
type Err = Void;
fn try_from_raw(raw: raw::NameEvent) -> Result<Self, (Self::Err, Self::Raw)> {
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<Self, (Self::Err, Self::Raw)> {
Ok(Self { name: raw.name })
fn from_raw(raw: raw::NameEventContent) -> Self {
Self { name: raw.name }
}
}

View File

@ -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<Self, (Self::Err, Self::Raw)> {
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<Self, (Self::Err, Self::Raw)> {
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,
})
}
}
}

View File

@ -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<String>,
}
impl TryFromRaw for ServerAclEvent {
impl FromRaw for ServerAclEvent {
type Raw = raw::ServerAclEvent;
type Err = Void;
fn try_from_raw(raw: raw::ServerAclEvent) -> Result<Self, (Self::Err, Self::Raw)> {
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<Self, (Self::Err, Self::Raw)> {
Ok(Self {
fn from_raw(raw: raw::ServerAclEventContent) -> Self {
Self {
allow_ip_literals: raw.allow_ip_literals,
allow: raw.allow,
deny: raw.deny,
})
}
}
}