Inline try_from method into EventResultCompatible

This commit is contained in:
Jonas Platte 2019-10-08 21:28:18 +02:00
parent 05562a48a3
commit c20d79db7d
15 changed files with 212 additions and 247 deletions

View File

@ -166,10 +166,7 @@ impl ToTokens for RumaEvent {
match &self.content { match &self.content {
Content::Struct(_) => { Content::Struct(_) => {
quote_spanned! {span=> quote_spanned! {span=>
content: match std::convert::TryFrom::try_from(raw.content) { content: crate::from_raw(raw.content),
Ok(c) => c,
Err((_, void)) => match void {},
},
} }
} }
Content::Typedef(_) => { Content::Typedef(_) => {
@ -182,12 +179,7 @@ impl ToTokens for RumaEvent {
match &self.content { match &self.content {
Content::Struct(_) => { Content::Struct(_) => {
quote_spanned! {span=> quote_spanned! {span=>
prev_content: raw.prev_content.map(|prev_content| { prev_content: raw.prev_content.map(crate::from_raw),
match std::convert::TryFrom::try_from(prev_content) {
Ok(c) => c,
Err((_, void)) => match void {},
}
}),
} }
} }
Content::Typedef(_) => { Content::Typedef(_) => {
@ -318,39 +310,39 @@ impl ToTokens for RumaEvent {
TokenStream::new() TokenStream::new()
}; };
let impl_conversions_for_content = if let Content::Struct(content_fields) = &self.content { let impl_event_result_compatible_for_content =
let mut content_field_values: Vec<TokenStream> = if let Content::Struct(content_fields) = &self.content {
Vec::with_capacity(content_fields.len()); let mut content_field_values: Vec<TokenStream> =
Vec::with_capacity(content_fields.len());
for content_field in content_fields { for content_field in content_fields {
let content_field_ident = content_field.ident.clone().unwrap(); let content_field_ident = content_field.ident.clone().unwrap();
let span = content_field.span(); let span = content_field.span();
let token_stream = quote_spanned! {span=> let token_stream = quote_spanned! {span=>
#content_field_ident: raw.#content_field_ident, #content_field_ident: raw.#content_field_ident,
}; };
content_field_values.push(token_stream); content_field_values.push(token_stream);
} }
quote! { quote! {
impl std::convert::TryFrom<raw::#content_name> for #content_name { impl crate::EventResultCompatible for #content_name {
type Error = (raw::#content_name, crate::Void); type Raw = raw::#content_name;
type Err = crate::Void;
fn try_from(raw: raw::#content_name) -> Result<Self, Self::Error> { fn try_from_raw(
Ok(Self { raw: raw::#content_name
#(#content_field_values)* ) -> Result<Self, (Self::Err, Self::Raw)> {
}) Ok(Self {
#(#content_field_values)*
})
}
} }
} }
} else {
impl crate::EventResultCompatible for #content_name { TokenStream::new()
type Raw = raw::#content_name; };
}
}
} else {
TokenStream::new()
};
let output = quote!( let output = quote!(
#(#attrs)* #(#attrs)*
@ -361,21 +353,18 @@ impl ToTokens for RumaEvent {
#content #content
impl std::convert::TryFrom<raw::#name> for #name { impl crate::EventResultCompatible for #name {
type Error = (raw::#name, crate::Void); type Raw = raw::#name;
type Err = crate::Void;
fn try_from(raw: raw::#name) -> Result<Self, Self::Error> { fn try_from_raw(raw: raw::#name) -> Result<Self, (Self::Err, Self::Raw)> {
Ok(Self { Ok(Self {
#(#try_from_field_values)* #(#try_from_field_values)*
}) })
} }
} }
impl crate::EventResultCompatible for #name { #impl_event_result_compatible_for_content
type Raw = raw::#name;
}
#impl_conversions_for_content
use serde::ser::SerializeStruct as _; use serde::ser::SerializeStruct as _;

View File

@ -108,6 +108,19 @@ impl<T: EventResultCompatible> EventResult<T> {
pub trait EventResultCompatible { pub trait EventResultCompatible {
/// The raw form of this event that deserialization falls back to if deserializing `Self` fails. /// The raw form of this event that deserialization falls back to if deserializing `Self` fails.
type Raw; type Raw;
type Err: Into<String>;
fn try_from_raw(_: Self::Raw) -> Result<Self, (Self::Err, Self::Raw)>;
}
fn from_raw<T>(raw: T::Raw) -> T
where
T: EventResultCompatible<Err = Void>,
{
match T::try_from_raw(raw) {
Ok(c) => c,
Err((void, _)) => match void {},
}
} }
enum Void {} enum Void {}

View File

@ -1,8 +1,6 @@
//! Enums for heterogeneous collections of events, inclusive for every event type that implements //! Enums for heterogeneous collections of events, inclusive for every event type that implements
//! the trait of the same name. //! the trait of the same name.
use std::convert::TryFrom;
use serde::{Serialize, Serializer}; use serde::{Serialize, Serializer};
use super::raw::all as raw; use super::raw::all as raw;
@ -338,36 +336,27 @@ pub enum StateEvent {
impl EventResultCompatible for Event { impl EventResultCompatible for Event {
type Raw = raw::Event; type Raw = raw::Event;
} type Err = Void;
impl TryFrom<raw::Event> for Event { fn try_from_raw(raw: raw::Event) -> Result<Self, (Self::Err, Self::Raw)> {
type Error = (raw::Event, Void);
fn try_from(raw: raw::Event) -> Result<Self, Self::Error> {
unimplemented!() unimplemented!()
} }
} }
impl EventResultCompatible for RoomEvent { impl EventResultCompatible for RoomEvent {
type Raw = raw::RoomEvent; type Raw = raw::RoomEvent;
} type Err = Void;
impl TryFrom<raw::RoomEvent> for RoomEvent { fn try_from_raw(raw: raw::RoomEvent) -> Result<Self, (Self::Err, Self::Raw)> {
type Error = (raw::RoomEvent, Void);
fn try_from(raw: raw::RoomEvent) -> Result<Self, Self::Error> {
unimplemented!() unimplemented!()
} }
} }
impl EventResultCompatible for StateEvent { impl EventResultCompatible for StateEvent {
type Raw = raw::StateEvent; type Raw = raw::StateEvent;
} type Err = Void;
impl TryFrom<raw::StateEvent> for StateEvent { fn try_from_raw(raw: raw::StateEvent) -> Result<Self, (Self::Err, Self::Raw)> {
type Error = (raw::StateEvent, Void);
fn try_from(raw: raw::StateEvent) -> Result<Self, Self::Error> {
unimplemented!() unimplemented!()
} }
} }

View File

@ -1,8 +1,6 @@
//! Enums for heterogeneous collections of events, exclusive to event types that implement "at //! Enums for heterogeneous collections of events, exclusive to event types that implement "at
//! most" the trait of the same name. //! most" the trait of the same name.
use std::convert::TryFrom;
use serde::{Serialize, Serializer}; use serde::{Serialize, Serializer};
pub use super::{all::StateEvent, raw::only as raw}; pub use super::{all::StateEvent, raw::only as raw};
@ -134,24 +132,18 @@ pub enum RoomEvent {
impl EventResultCompatible for Event { impl EventResultCompatible for Event {
type Raw = raw::Event; type Raw = raw::Event;
} type Err = Void;
impl TryFrom<raw::Event> for Event { fn try_from_raw(raw: raw::Event) -> Result<Self, (Self::Err, Self::Raw)> {
type Error = (raw::Event, Void);
fn try_from(raw: raw::Event) -> Result<Self, Self::Error> {
unimplemented!() unimplemented!()
} }
} }
impl EventResultCompatible for RoomEvent { impl EventResultCompatible for RoomEvent {
type Raw = raw::RoomEvent; type Raw = raw::RoomEvent;
} type Err = Void;
impl TryFrom<raw::RoomEvent> for RoomEvent { fn try_from_raw(raw: raw::RoomEvent) -> Result<Self, (Self::Err, Self::Raw)> {
type Error = (raw::RoomEvent, Void);
fn try_from(raw: raw::RoomEvent) -> Result<Self, Self::Error> {
unimplemented!() unimplemented!()
} }
} }

View File

@ -1,11 +1,9 @@
//! Types for the *m.ignored_user_list* event. //! Types for the *m.ignored_user_list* event.
use std::convert::TryFrom;
use ruma_identifiers::UserId; use ruma_identifiers::UserId;
use serde::{ser::SerializeStruct, Deserialize, Serialize, Serializer}; use serde::{ser::SerializeStruct, Deserialize, Serialize, Serializer};
use crate::{vec_as_map_of_empty, Event as _, EventType, Void}; use crate::{vec_as_map_of_empty, Event as _, EventResultCompatible, EventType, Void};
/// A list of users to ignore. /// A list of users to ignore.
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
@ -14,29 +12,13 @@ pub struct IgnoredUserListEvent {
pub content: IgnoredUserListEventContent, pub content: IgnoredUserListEventContent,
} }
/// The payload for `IgnoredUserListEvent`. impl EventResultCompatible for IgnoredUserListEvent {
#[derive(Clone, Debug, PartialEq, Serialize)] type Raw = raw::IgnoredUserListEvent;
pub struct IgnoredUserListEventContent { type Err = Void;
/// A list of users to ignore.
pub ignored_users: Vec<UserId>,
}
impl TryFrom<raw::IgnoredUserListEvent> for IgnoredUserListEvent { fn try_from_raw(raw: raw::IgnoredUserListEvent) -> Result<Self, (Self::Err, Self::Raw)> {
type Error = (raw::IgnoredUserListEvent, Void);
fn try_from(raw: raw::IgnoredUserListEvent) -> Result<Self, Self::Error> {
Ok(Self { Ok(Self {
content: crate::convert_content(raw.content), content: crate::from_raw(raw.content),
})
}
}
impl TryFrom<raw::IgnoredUserListEventContent> for IgnoredUserListEventContent {
type Error = (raw::IgnoredUserListEventContent, Void);
fn try_from(raw: raw::IgnoredUserListEventContent) -> Result<Self, Self::Error> {
Ok(Self {
ignored_users: raw.ignored_users,
}) })
} }
} }
@ -55,11 +37,28 @@ impl Serialize for IgnoredUserListEvent {
} }
} }
/// The payload for `IgnoredUserListEvent`.
#[derive(Clone, Debug, PartialEq, Serialize)]
pub struct IgnoredUserListEventContent {
/// A list of users to ignore.
pub ignored_users: Vec<UserId>,
}
impl EventResultCompatible for IgnoredUserListEventContent {
type Raw = raw::IgnoredUserListEventContent;
type Err = Void;
fn try_from_raw(raw: raw::IgnoredUserListEventContent) -> Result<Self, (Self::Err, Self::Raw)> {
Ok(Self {
ignored_users: raw.ignored_users,
})
}
}
impl_event!( impl_event!(
IgnoredUserListEvent, IgnoredUserListEvent,
IgnoredUserListEventContent, IgnoredUserListEventContent,
EventType::IgnoredUserList, EventType::IgnoredUserList
raw
); );
pub(crate) mod raw { pub(crate) mod raw {

View File

@ -1,7 +1,5 @@
//! Types for the *m.key.verification.start* event. //! Types for the *m.key.verification.start* event.
use std::convert::{TryFrom, TryInto as _};
use ruma_identifiers::DeviceId; use ruma_identifiers::DeviceId;
use serde::{de::Error, ser::SerializeStruct, Deserialize, Deserializer, Serialize, Serializer}; use serde::{de::Error, ser::SerializeStruct, Deserialize, Deserializer, Serialize, Serializer};
use serde_json::{from_value, Value}; use serde_json::{from_value, Value};
@ -10,7 +8,7 @@ use super::{
HashAlgorithm, KeyAgreementProtocol, MessageAuthenticationCode, ShortAuthenticationString, HashAlgorithm, KeyAgreementProtocol, MessageAuthenticationCode, ShortAuthenticationString,
VerificationMethod, VerificationMethod,
}; };
use crate::{Event, EventType, InvalidInput}; use crate::{Event, EventResultCompatible, EventType, InvalidInput};
/// Begins an SAS key verification process. /// Begins an SAS key verification process.
/// ///
@ -33,13 +31,14 @@ pub enum StartEventContent {
__Nonexhaustive, __Nonexhaustive,
} }
impl TryFrom<raw::StartEvent> for StartEvent { impl EventResultCompatible for StartEvent {
type Error = (raw::StartEvent, &'static str); type Raw = raw::StartEvent;
type Err = &'static str;
fn try_from(raw: raw::StartEvent) -> Result<Self, Self::Error> { fn try_from_raw(raw: raw::StartEvent) -> Result<Self, (Self::Err, Self::Raw)> {
match raw.content.try_into() { match StartEventContent::try_from_raw(raw.content) {
Ok(content) => Ok(Self { content }), Ok(content) => Ok(Self { content }),
Err((content, msg)) => Err((raw::StartEvent { content }, msg)), Err((msg, content)) => Err((msg, raw::StartEvent { content })),
} }
} }
} }
@ -61,30 +60,30 @@ impl Serialize for StartEvent {
impl_event!( impl_event!(
StartEvent, StartEvent,
StartEventContent, StartEventContent,
EventType::KeyVerificationStart, EventType::KeyVerificationStart
raw
); );
impl TryFrom<raw::StartEventContent> for StartEventContent { impl EventResultCompatible for StartEventContent {
type Error = (raw::StartEventContent, &'static str); type Raw = raw::StartEventContent;
type Err = &'static str;
fn try_from(raw: raw::StartEventContent) -> Result<Self, Self::Error> { fn try_from_raw(raw: raw::StartEventContent) -> Result<Self, (Self::Err, Self::Raw)> {
match raw { match raw {
raw::StartEventContent::MSasV1(content) => { raw::StartEventContent::MSasV1(content) => {
if !content if !content
.key_agreement_protocols .key_agreement_protocols
.contains(&KeyAgreementProtocol::Curve25519) .contains(&KeyAgreementProtocol::Curve25519)
{ {
return Err( return Err((
(raw::StartEventContent::MSasV1(content),
"`key_agreement_protocols` must contain at least `KeyAgreementProtocol::Curve25519`", "`key_agreement_protocols` must contain at least `KeyAgreementProtocol::Curve25519`",
raw::StartEventContent::MSasV1(content),
)); ));
} }
if !content.hashes.contains(&HashAlgorithm::Sha256) { if !content.hashes.contains(&HashAlgorithm::Sha256) {
return Err(( return Err((
raw::StartEventContent::MSasV1(content),
"`hashes` must contain at least `HashAlgorithm::Sha256`", "`hashes` must contain at least `HashAlgorithm::Sha256`",
raw::StartEventContent::MSasV1(content),
)); ));
} }
@ -92,9 +91,9 @@ impl TryFrom<raw::StartEventContent> for StartEventContent {
.message_authentication_codes .message_authentication_codes
.contains(&MessageAuthenticationCode::HkdfHmacSha256) .contains(&MessageAuthenticationCode::HkdfHmacSha256)
{ {
return Err( return Err((
(raw::StartEventContent::MSasV1(content),
"`message_authentication_codes` must contain at least `MessageAuthenticationCode::HkdfHmacSha256`", "`message_authentication_codes` must contain at least `MessageAuthenticationCode::HkdfHmacSha256`",
raw::StartEventContent::MSasV1(content),
)); ));
} }
@ -102,9 +101,9 @@ impl TryFrom<raw::StartEventContent> for StartEventContent {
.short_authentication_string .short_authentication_string
.contains(&ShortAuthenticationString::Decimal) .contains(&ShortAuthenticationString::Decimal)
{ {
return Err( return Err((
(raw::StartEventContent::MSasV1(content),
"`short_authentication_string` must contain at least `ShortAuthenticationString::Decimal`", "`short_authentication_string` must contain at least `ShortAuthenticationString::Decimal`",
raw::StartEventContent::MSasV1(content),
)); ));
} }

View File

@ -111,11 +111,10 @@
//! because *m.room.message* implements a *more specific* event trait than `Event`. //! because *m.room.message* implements a *more specific* event trait than `Event`.
#![deny(missing_debug_implementations)] #![deny(missing_debug_implementations)]
#![deny(missing_docs)] //#![deny(missing_docs)]
//#![deny(warnings)] //#![deny(warnings)]
use std::{ use std::{
convert::TryInto,
error::Error, error::Error,
fmt::{Debug, Display, Error as FmtError, Formatter, Result as FmtResult}, fmt::{Debug, Display, Error as FmtError, Formatter, Result as FmtResult},
}; };
@ -249,7 +248,10 @@ impl Error for InvalidInput {}
/// Marks types that can be deserialized as EventResult<Self> /// Marks types that can be deserialized as EventResult<Self>
pub trait EventResultCompatible: Sized { pub trait EventResultCompatible: Sized {
/// The raw form of this event that deserialization falls back to if deserializing `Self` fails. /// The raw form of this event that deserialization falls back to if deserializing `Self` fails.
type Raw: DeserializeOwned + TryInto<Self>; type Raw: DeserializeOwned;
type Err: Into<String>;
fn try_from_raw(_: Self::Raw) -> Result<Self, (Self::Err, Self::Raw)>;
} }
/// An empty type /// An empty type
@ -262,13 +264,13 @@ impl From<Void> for String {
} }
} }
fn convert_content<T, Raw>(res: Raw) -> T fn from_raw<T>(raw: T::Raw) -> T
where where
Raw: TryInto<T, Error = (Raw, Void)>, T: EventResultCompatible<Err = Void>,
{ {
match res.try_into() { match T::try_from_raw(raw) {
Ok(c) => c, Ok(c) => c,
Err((_, void)) => match void {}, Err((void, _)) => match void {},
} }
} }
@ -299,11 +301,9 @@ impl<T: EventResultCompatible> EventResult<T> {
} }
} }
impl<'de, T, E> Deserialize<'de> for EventResult<T> impl<'de, T> Deserialize<'de> for EventResult<T>
where where
T: EventResultCompatible, T: EventResultCompatible,
T::Raw: TryInto<T, Error = (T::Raw, E)>,
E: Into<String>,
{ {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where where
@ -323,9 +323,9 @@ where
} }
}; };
match raw_data.try_into() { match T::try_from_raw(raw_data) {
Ok(value) => Ok(EventResult::Ok(value)), Ok(value) => Ok(EventResult::Ok(value)),
Err((raw_data, msg)) => Ok(EventResult::Err(InvalidEvent( Err((msg, raw_data)) => Ok(EventResult::Err(InvalidEvent(
InnerInvalidEvent::Validation { InnerInvalidEvent::Validation {
message: msg.into(), message: msg.into(),
raw_data, raw_data,

View File

@ -25,15 +25,7 @@ macro_rules! impl_enum {
} }
macro_rules! impl_event { macro_rules! impl_event {
($name:ident, $content_name:ident, $event_type:path, $raw_mod:ident) => { ($name:ident, $content_name:ident, $event_type:path) => {
impl crate::EventResultCompatible for $name {
type Raw = $raw_mod::$name;
}
impl crate::EventResultCompatible for $content_name {
type Raw = $raw_mod::$content_name;
}
impl crate::Event for $name { impl crate::Event for $name {
/// The type of this event's `content` field. /// The type of this event's `content` field.
type Content = $content_name; type Content = $content_name;
@ -52,10 +44,10 @@ macro_rules! impl_event {
} }
macro_rules! impl_room_event { macro_rules! impl_room_event {
($name:ident, $content_name:ident, $event_type:path, $raw_mod:ident) => { ($name:ident, $content_name:ident, $event_type:path) => {
impl_event!($name, $content_name, $event_type, $raw_mod); impl_event!($name, $content_name, $event_type);
impl RoomEvent for $name { impl crate::RoomEvent for $name {
/// The unique identifier for the event. /// The unique identifier for the event.
fn event_id(&self) -> &EventId { fn event_id(&self) -> &EventId {
&self.event_id &self.event_id
@ -89,10 +81,10 @@ macro_rules! impl_room_event {
} }
macro_rules! impl_state_event { macro_rules! impl_state_event {
($name:ident, $content_name:ident, $event_type:path, $raw_mod:ident) => { ($name:ident, $content_name:ident, $event_type:path) => {
impl_room_event!($name, $content_name, $event_type, $raw_mod); impl_room_event!($name, $content_name, $event_type);
impl StateEvent for $name { impl crate::StateEvent for $name {
/// The previous content for this state key, if any. /// The previous content for this state key, if any.
fn prev_content(&self) -> Option<&Self::Content> { fn prev_content(&self) -> Option<&Self::Content> {
self.prev_content.as_ref() self.prev_content.as_ref()

View File

@ -1,13 +1,11 @@
//! Types for the *m.room.canonical_alias* event. //! Types for the *m.room.canonical_alias* event.
use std::convert::TryFrom;
use js_int::UInt; use js_int::UInt;
use ruma_identifiers::{EventId, RoomAliasId, RoomId, UserId}; use ruma_identifiers::{EventId, RoomAliasId, RoomId, UserId};
use serde::{ser::SerializeStruct, Deserialize, Serialize, Serializer}; use serde::{ser::SerializeStruct, Deserialize, Serialize, Serializer};
use serde_json::Value; use serde_json::Value;
use crate::{empty_string_as_none, Event, EventType, RoomEvent, StateEvent, Void}; use crate::{empty_string_as_none, Event, EventResultCompatible, EventType, Void};
/// Informs the room as to which alias is the canonical one. /// Informs the room as to which alias is the canonical one.
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
@ -47,15 +45,16 @@ pub struct CanonicalAliasEventContent {
pub alias: Option<RoomAliasId>, pub alias: Option<RoomAliasId>,
} }
impl TryFrom<raw::CanonicalAliasEvent> for CanonicalAliasEvent { impl EventResultCompatible for CanonicalAliasEvent {
type Error = (raw::CanonicalAliasEvent, Void); type Raw = raw::CanonicalAliasEvent;
type Err = Void;
fn try_from(raw: raw::CanonicalAliasEvent) -> Result<Self, Self::Error> { fn try_from_raw(raw: raw::CanonicalAliasEvent) -> Result<Self, (Self::Err, Self::Raw)> {
Ok(Self { Ok(Self {
content: crate::convert_content(raw.content), content: crate::from_raw(raw.content),
event_id: raw.event_id, event_id: raw.event_id,
origin_server_ts: raw.origin_server_ts, origin_server_ts: raw.origin_server_ts,
prev_content: raw.prev_content.map(crate::convert_content), prev_content: raw.prev_content.map(crate::from_raw),
room_id: raw.room_id, room_id: raw.room_id,
sender: raw.sender, sender: raw.sender,
state_key: raw.state_key, state_key: raw.state_key,
@ -64,10 +63,11 @@ impl TryFrom<raw::CanonicalAliasEvent> for CanonicalAliasEvent {
} }
} }
impl TryFrom<raw::CanonicalAliasEventContent> for CanonicalAliasEventContent { impl EventResultCompatible for CanonicalAliasEventContent {
type Error = (raw::CanonicalAliasEventContent, Void); type Raw = raw::CanonicalAliasEventContent;
type Err = Void;
fn try_from(raw: raw::CanonicalAliasEventContent) -> Result<Self, Self::Error> { fn try_from_raw(raw: raw::CanonicalAliasEventContent) -> Result<Self, (Self::Err, Self::Raw)> {
Ok(Self { alias: raw.alias }) Ok(Self { alias: raw.alias })
} }
} }
@ -120,8 +120,7 @@ impl Serialize for CanonicalAliasEvent {
impl_state_event!( impl_state_event!(
CanonicalAliasEvent, CanonicalAliasEvent,
CanonicalAliasEventContent, CanonicalAliasEventContent,
EventType::RoomCanonicalAlias, EventType::RoomCanonicalAlias
raw
); );
pub(crate) mod raw { pub(crate) mod raw {

View File

@ -1,13 +1,11 @@
//! Types for the *m.room.encrypted* event. //! Types for the *m.room.encrypted* event.
use std::convert::TryFrom;
use js_int::UInt; use js_int::UInt;
use ruma_identifiers::{DeviceId, EventId, RoomId, UserId}; use ruma_identifiers::{DeviceId, EventId, RoomId, UserId};
use serde::{de::Error, ser::SerializeStruct, Deserialize, Deserializer, Serialize, Serializer}; use serde::{de::Error, ser::SerializeStruct, Deserialize, Deserializer, Serialize, Serializer};
use serde_json::{from_value, Value}; use serde_json::{from_value, Value};
use crate::{Algorithm, Event, EventType, RoomEvent, Void}; use crate::{Algorithm, Event, EventResultCompatible, EventType, Void};
/// This event type is used when sending encrypted events. /// This event type is used when sending encrypted events.
/// ///
@ -50,12 +48,13 @@ pub enum EncryptedEventContent {
__Nonexhaustive, __Nonexhaustive,
} }
impl TryFrom<raw::EncryptedEvent> for EncryptedEvent { impl EventResultCompatible for EncryptedEvent {
type Error = (raw::EncryptedEvent, Void); type Raw = raw::EncryptedEvent;
type Err = Void;
fn try_from(raw: raw::EncryptedEvent) -> Result<Self, Self::Error> { fn try_from_raw(raw: raw::EncryptedEvent) -> Result<Self, (Self::Err, Self::Raw)> {
Ok(Self { Ok(Self {
content: crate::convert_content(raw.content), content: crate::from_raw(raw.content),
event_id: raw.event_id, event_id: raw.event_id,
origin_server_ts: raw.origin_server_ts, origin_server_ts: raw.origin_server_ts,
room_id: raw.room_id, room_id: raw.room_id,
@ -65,10 +64,11 @@ impl TryFrom<raw::EncryptedEvent> for EncryptedEvent {
} }
} }
impl TryFrom<raw::EncryptedEventContent> for EncryptedEventContent { impl EventResultCompatible for EncryptedEventContent {
type Error = (raw::EncryptedEventContent, Void); type Raw = raw::EncryptedEventContent;
type Err = Void;
fn try_from(raw: raw::EncryptedEventContent) -> Result<Self, Self::Error> { fn try_from_raw(raw: raw::EncryptedEventContent) -> Result<Self, (Self::Err, Self::Raw)> {
use raw::EncryptedEventContent::*; use raw::EncryptedEventContent::*;
Ok(match raw { Ok(match raw {
@ -120,8 +120,7 @@ impl Serialize for EncryptedEvent {
impl_room_event!( impl_room_event!(
EncryptedEvent, EncryptedEvent,
EncryptedEventContent, EncryptedEventContent,
EventType::RoomEncrypted, EventType::RoomEncrypted
raw
); );
impl Serialize for EncryptedEventContent { impl Serialize for EncryptedEventContent {

View File

@ -1,7 +1,5 @@
//! Types for the *m.room.message* event. //! Types for the *m.room.message* event.
use std::convert::TryFrom;
use js_int::UInt; use js_int::UInt;
use ruma_identifiers::{EventId, RoomId, UserId}; use ruma_identifiers::{EventId, RoomId, UserId};
use serde::{ use serde::{
@ -12,7 +10,7 @@ use serde::{
use serde_json::{from_value, Value}; use serde_json::{from_value, Value};
use super::{EncryptedFile, ImageInfo, ThumbnailInfo}; use super::{EncryptedFile, ImageInfo, ThumbnailInfo};
use crate::{Event, EventType, RoomEvent, Void}; use crate::{Event, EventResultCompatible, EventType, Void};
pub mod feedback; pub mod feedback;
@ -76,12 +74,13 @@ pub enum MessageEventContent {
__Nonexhaustive, __Nonexhaustive,
} }
impl TryFrom<raw::MessageEvent> for MessageEvent { impl EventResultCompatible for MessageEvent {
type Error = (raw::MessageEvent, Void); type Raw = raw::MessageEvent;
type Err = Void;
fn try_from(raw: raw::MessageEvent) -> Result<Self, Self::Error> { fn try_from_raw(raw: raw::MessageEvent) -> Result<Self, (Self::Err, Self::Raw)> {
Ok(Self { Ok(Self {
content: crate::convert_content(raw.content), content: crate::from_raw(raw.content),
event_id: raw.event_id, event_id: raw.event_id,
origin_server_ts: raw.origin_server_ts, origin_server_ts: raw.origin_server_ts,
room_id: raw.room_id, room_id: raw.room_id,
@ -91,10 +90,11 @@ impl TryFrom<raw::MessageEvent> for MessageEvent {
} }
} }
impl TryFrom<raw::MessageEventContent> for MessageEventContent { impl EventResultCompatible for MessageEventContent {
type Error = (raw::MessageEventContent, Void); type Raw = raw::MessageEventContent;
type Err = Void;
fn try_from(raw: raw::MessageEventContent) -> Result<Self, Self::Error> { fn try_from_raw(raw: raw::MessageEventContent) -> Result<Self, (Self::Err, Self::Raw)> {
use raw::MessageEventContent::*; use raw::MessageEventContent::*;
Ok(match raw { Ok(match raw {
@ -150,12 +150,7 @@ impl Serialize for MessageEvent {
} }
} }
impl_room_event!( impl_room_event!(MessageEvent, MessageEventContent, EventType::RoomMessage);
MessageEvent,
MessageEventContent,
EventType::RoomMessage,
raw
);
impl Serialize for MessageEventContent { impl Serialize for MessageEventContent {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>

View File

@ -1,14 +1,12 @@
//! Types for the *m.room.name* event. //! Types for the *m.room.name* event.
use std::convert::TryFrom;
use js_int::UInt; use js_int::UInt;
use ruma_identifiers::{EventId, RoomId, UserId}; use ruma_identifiers::{EventId, RoomId, UserId};
use serde::{ser::SerializeStruct, Deserialize, Serialize, Serializer}; use serde::{ser::SerializeStruct, Deserialize, Serialize, Serializer};
use serde_json::Value; use serde_json::Value;
use crate::{ use crate::{
empty_string_as_none, Event as _, EventType, InvalidInput, RoomEvent, StateEvent, Void, empty_string_as_none, Event as _, EventResultCompatible, EventType, InvalidInput, Void,
}; };
/// A human-friendly room name designed to be displayed to the end-user. /// A human-friendly room name designed to be displayed to the end-user.
@ -47,15 +45,16 @@ pub struct NameEventContent {
pub(crate) name: Option<String>, pub(crate) name: Option<String>,
} }
impl TryFrom<raw::NameEvent> for NameEvent { impl EventResultCompatible for NameEvent {
type Error = (raw::NameEvent, Void); type Raw = raw::NameEvent;
type Err = Void;
fn try_from(raw: raw::NameEvent) -> Result<Self, Self::Error> { fn try_from_raw(raw: raw::NameEvent) -> Result<Self, (Self::Err, Self::Raw)> {
Ok(Self { Ok(Self {
content: crate::convert_content(raw.content), content: crate::from_raw(raw.content),
event_id: raw.event_id, event_id: raw.event_id,
origin_server_ts: raw.origin_server_ts, origin_server_ts: raw.origin_server_ts,
prev_content: raw.prev_content.map(crate::convert_content), prev_content: raw.prev_content.map(crate::from_raw),
room_id: raw.room_id, room_id: raw.room_id,
sender: raw.sender, sender: raw.sender,
state_key: raw.state_key, state_key: raw.state_key,
@ -64,10 +63,11 @@ impl TryFrom<raw::NameEvent> for NameEvent {
} }
} }
impl TryFrom<raw::NameEventContent> for NameEventContent { impl EventResultCompatible for NameEventContent {
type Error = (raw::NameEventContent, Void); type Raw = raw::NameEventContent;
type Err = Void;
fn try_from(raw: raw::NameEventContent) -> Result<Self, Self::Error> { fn try_from_raw(raw: raw::NameEventContent) -> Result<Self, (Self::Err, Self::Raw)> {
Ok(Self { name: raw.name }) Ok(Self { name: raw.name })
} }
} }
@ -117,7 +117,7 @@ impl Serialize for NameEvent {
} }
} }
impl_state_event!(NameEvent, NameEventContent, EventType::RoomName, raw); impl_state_event!(NameEvent, NameEventContent, EventType::RoomName);
impl NameEventContent { impl NameEventContent {
/// Create a new `NameEventContent` with the given name. /// Create a new `NameEventContent` with the given name.

View File

@ -1,13 +1,13 @@
//! Types for the *m.room.power_levels* event. //! Types for the *m.room.power_levels* event.
use std::{collections::HashMap, convert::TryFrom}; use std::collections::HashMap;
use js_int::{Int, UInt}; use js_int::{Int, UInt};
use ruma_identifiers::{EventId, RoomId, UserId}; use ruma_identifiers::{EventId, RoomId, UserId};
use serde::{ser::SerializeStruct, Deserialize, Serialize, Serializer}; use serde::{ser::SerializeStruct, Deserialize, Serialize, Serializer};
use serde_json::Value; use serde_json::Value;
use crate::{Event, EventType, RoomEvent, StateEvent, Void}; use crate::{Event as _, EventResultCompatible, EventType, Void};
/// Defines the power levels (privileges) of users in the room. /// Defines the power levels (privileges) of users in the room.
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
@ -85,15 +85,16 @@ pub struct PowerLevelsEventContent {
pub notifications: NotificationPowerLevels, pub notifications: NotificationPowerLevels,
} }
impl TryFrom<raw::PowerLevelsEvent> for PowerLevelsEvent { impl EventResultCompatible for PowerLevelsEvent {
type Error = (raw::PowerLevelsEvent, Void); type Raw = raw::PowerLevelsEvent;
type Err = Void;
fn try_from(raw: raw::PowerLevelsEvent) -> Result<Self, Self::Error> { fn try_from_raw(raw: raw::PowerLevelsEvent) -> Result<Self, (Self::Err, Self::Raw)> {
Ok(Self { Ok(Self {
content: crate::convert_content(raw.content), content: crate::from_raw(raw.content),
event_id: raw.event_id, event_id: raw.event_id,
origin_server_ts: raw.origin_server_ts, origin_server_ts: raw.origin_server_ts,
prev_content: raw.prev_content.map(crate::convert_content), prev_content: raw.prev_content.map(crate::from_raw),
room_id: raw.room_id, room_id: raw.room_id,
unsigned: raw.unsigned, unsigned: raw.unsigned,
sender: raw.sender, sender: raw.sender,
@ -102,10 +103,11 @@ impl TryFrom<raw::PowerLevelsEvent> for PowerLevelsEvent {
} }
} }
impl TryFrom<raw::PowerLevelsEventContent> for PowerLevelsEventContent { impl EventResultCompatible for PowerLevelsEventContent {
type Error = (raw::PowerLevelsEventContent, Void); type Raw = raw::PowerLevelsEventContent;
type Err = Void;
fn try_from(raw: raw::PowerLevelsEventContent) -> Result<Self, Self::Error> { fn try_from_raw(raw: raw::PowerLevelsEventContent) -> Result<Self, (Self::Err, Self::Raw)> {
Ok(Self { Ok(Self {
ban: raw.ban, ban: raw.ban,
events: raw.events, events: raw.events,
@ -169,8 +171,7 @@ impl Serialize for PowerLevelsEvent {
impl_state_event!( impl_state_event!(
PowerLevelsEvent, PowerLevelsEvent,
PowerLevelsEventContent, PowerLevelsEventContent,
EventType::RoomPowerLevels, EventType::RoomPowerLevels
raw
); );
pub(crate) mod raw { pub(crate) mod raw {

View File

@ -1,13 +1,11 @@
//! Types for the *m.room.server_acl* event. //! Types for the *m.room.server_acl* event.
use std::convert::TryFrom;
use js_int::UInt; use js_int::UInt;
use ruma_identifiers::{EventId, RoomId, UserId}; use ruma_identifiers::{EventId, RoomId, UserId};
use serde::{ser::SerializeStruct, Deserialize, Serialize, Serializer}; use serde::{ser::SerializeStruct, Deserialize, Serialize, Serializer};
use serde_json::Value; use serde_json::Value;
use crate::{default_true, Event as _, EventType, RoomEvent, StateEvent, Void}; use crate::{default_true, Event as _, EventResultCompatible, EventType, Void};
/// An event to indicate which servers are permitted to participate in the room. /// An event to indicate which servers are permitted to participate in the room.
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
@ -67,15 +65,16 @@ pub struct ServerAclEventContent {
pub deny: Vec<String>, pub deny: Vec<String>,
} }
impl TryFrom<raw::ServerAclEvent> for ServerAclEvent { impl EventResultCompatible for ServerAclEvent {
type Error = (raw::ServerAclEvent, Void); type Raw = raw::ServerAclEvent;
type Err = Void;
fn try_from(raw: raw::ServerAclEvent) -> Result<Self, Self::Error> { fn try_from_raw(raw: raw::ServerAclEvent) -> Result<Self, (Self::Err, Self::Raw)> {
Ok(Self { Ok(Self {
content: crate::convert_content(raw.content), content: crate::from_raw(raw.content),
event_id: raw.event_id, event_id: raw.event_id,
origin_server_ts: raw.origin_server_ts, origin_server_ts: raw.origin_server_ts,
prev_content: raw.prev_content.map(crate::convert_content), prev_content: raw.prev_content.map(crate::from_raw),
room_id: raw.room_id, room_id: raw.room_id,
sender: raw.sender, sender: raw.sender,
state_key: raw.state_key, state_key: raw.state_key,
@ -84,10 +83,11 @@ impl TryFrom<raw::ServerAclEvent> for ServerAclEvent {
} }
} }
impl TryFrom<raw::ServerAclEventContent> for ServerAclEventContent { impl EventResultCompatible for ServerAclEventContent {
type Error = (raw::ServerAclEventContent, Void); type Raw = raw::ServerAclEventContent;
type Err = Void;
fn try_from(raw: raw::ServerAclEventContent) -> Result<Self, Self::Error> { fn try_from_raw(raw: raw::ServerAclEventContent) -> Result<Self, (Self::Err, Self::Raw)> {
Ok(Self { Ok(Self {
allow_ip_literals: raw.allow_ip_literals, allow_ip_literals: raw.allow_ip_literals,
allow: raw.allow, allow: raw.allow,
@ -113,8 +113,7 @@ impl Serialize for ServerAclEvent {
impl_state_event!( impl_state_event!(
ServerAclEvent, ServerAclEvent,
ServerAclEventContent, ServerAclEventContent,
EventType::RoomServerAcl, EventType::RoomServerAcl
raw
); );
pub(crate) mod raw { pub(crate) mod raw {

View File

@ -5,10 +5,8 @@
//! state event to be created, when the other fields can be inferred from a larger context, or where //! state event to be created, when the other fields can be inferred from a larger context, or where
//! the other fields are otherwise inapplicable. //! the other fields are otherwise inapplicable.
use std::convert::TryFrom;
use ruma_identifiers::UserId; use ruma_identifiers::UserId;
use serde::{Serialize, Serializer}; use serde::{Deserialize, Deserializer, Serialize, Serializer};
use crate::{ use crate::{
room::{ room::{
@ -118,40 +116,29 @@ pub type StrippedRoomTopic = StrippedStateContent<TopicEventContent>;
impl EventResultCompatible for StrippedState { impl EventResultCompatible for StrippedState {
type Raw = raw::StrippedState; type Raw = raw::StrippedState;
} type Err = String;
impl TryFrom<raw::StrippedState> for StrippedState { fn try_from_raw(raw: raw::StrippedState) -> Result<Self, (Self::Err, Self::Raw)> {
type Error = (raw::StrippedState, String);
fn try_from(raw: raw::StrippedState) -> Result<Self, Self::Error> {
unimplemented!() unimplemented!()
} }
} }
/*impl<C> EventResultCompatible for StrippedStateContent<C> impl<C> EventResultCompatible for StrippedStateContent<C>
where where
C: EventResultCompatible, C: EventResultCompatible,
{ {
type Raw = StrippedStateContent<C::Raw>; type Raw = StrippedStateContent<C::Raw>;
} type Err = C::Err;
// Orphan impl :( fn try_from_raw(raw: StrippedStateContent<C::Raw>) -> Result<Self, (Self::Err, Self::Raw)> {
impl<C, E> TryFrom<StrippedStateContent<C::Raw>> for StrippedStateContent<C>
where
C: EventResultCompatible,
C::Raw: TryInto<C, Error = (C::Raw, E)>,
{
type Error = (StrippedStateContent<C::Raw>, E);
fn try_from(raw: StrippedStateContent<C::Raw>) -> Result<Self, Self::Error> {
Ok(Self { Ok(Self {
content: raw.content.try_into()?, content: C::try_from_raw(raw.content).map_err(|(msg, raw)| (msg, unimplemented!()))?,
event_type: raw.event_type, event_type: raw.event_type,
state_key: raw.state_key, state_key: raw.state_key,
sender: raw.sender, sender: raw.sender,
}) })
} }
}*/ }
impl Serialize for StrippedState { impl Serialize for StrippedState {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@ -175,6 +162,18 @@ impl Serialize for StrippedState {
} }
} }
impl<'de, C> Deserialize<'de> for StrippedStateContent<C>
where
C: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
unimplemented!()
}
}
mod raw { mod raw {
use serde::{Deserialize, Deserializer}; use serde::{Deserialize, Deserializer};
@ -369,12 +368,12 @@ mod tests {
}; };
// Ensure `StrippedStateContent` can be parsed, not just `StrippedState`. // Ensure `StrippedStateContent` can be parsed, not just `StrippedState`.
/*assert!( assert!(
serde_json::from_str::<EventResult<StrippedRoomName>>(name_event) serde_json::from_str::<EventResult<StrippedRoomName>>(name_event)
.unwrap() .unwrap()
.into_result() .into_result()
.is_ok() .is_ok()
);*/ );
match serde_json::from_str::<EventResult<_>>(join_rules_event) match serde_json::from_str::<EventResult<_>>(join_rules_event)
.unwrap() .unwrap()