events: Remove EventContent::from_parts

This commit is contained in:
Kévin Commaille 2023-01-10 11:32:54 +01:00 committed by Kévin Commaille
parent 9a9bd2c933
commit 1d8ea75f6f
14 changed files with 34 additions and 184 deletions

View File

@ -55,6 +55,8 @@ Breaking changes:
* Replace it with a bound on `DeserializeOwned`
* Remove `Raw::deserialize_content`
* Instead, use `.deserialize_as::<T>()` or `.cast_ref::<T>().deserialize_with_type()`
* Remove `EventContent::from_parts`
* Replace it with `EventContentFromType::from_parts`
Improvements:

View File

@ -29,10 +29,6 @@ macro_rules! custom_event_content {
fn event_type(&self) -> Self::EventType {
self.event_type[..].into()
}
fn from_parts(event_type: &str, _content: &RawJsonValue) -> serde_json::Result<Self> {
Ok(Self { event_type: event_type.into() })
}
}
impl EventContentFromType for $i {

View File

@ -21,10 +21,6 @@ pub trait EventContent: Sized + Serialize {
/// Get the event's type, like `m.room.message`.
fn event_type(&self) -> Self::EventType;
/// Constructs the given event content.
#[doc(hidden)]
fn from_parts(event_type: &str, content: &RawJsonValue) -> serde_json::Result<Self>;
}
impl<T> Raw<T>
@ -34,7 +30,7 @@ where
{
/// Try to deserialize the JSON as an event's content with the given event type.
pub fn deserialize_with_type(&self, event_type: T::EventType) -> serde_json::Result<T> {
<T as EventContentFromType>::from_parts(&event_type.to_string(), self.json())
T::from_parts(&event_type.to_string(), self.json())
}
}

View File

@ -5,7 +5,7 @@ use serde::{ser::SerializeStruct, Deserialize, Deserializer, Serialize};
use serde_json::value::RawValue as RawJsonValue;
use super::{
EphemeralRoomEventContent, EventContent, GlobalAccountDataEventContent,
EphemeralRoomEventContent, EventContent, EventContentFromType, GlobalAccountDataEventContent,
MessageLikeEventContent, MessageLikeEventType, MessageLikeUnsigned, OriginalStateEventContent,
RedactContent, RedactedMessageLikeEventContent, RedactedStateEventContent, RedactedUnsigned,
RedactionDeHelper, RoomAccountDataEventContent, StateEventContent, StateEventType,
@ -551,8 +551,8 @@ macro_rules! impl_possibly_redacted_event {
impl<'de, C> Deserialize<'de> for $ty<C>
where
C: $content_trait + RedactContent,
C::Redacted: $redacted_content_trait,
C: $content_trait + EventContentFromType + RedactContent,
C::Redacted: $redacted_content_trait + EventContentFromType,
$( C::Redacted: $trait<StateKey = C::StateKey>, )?
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>

View File

@ -4,7 +4,6 @@
use ruma_macros::EventContent;
use serde::{Deserialize, Serialize};
use serde_json::value::RawValue as RawJsonValue;
use super::{PolicyRuleEventContent, PossiblyRedactedPolicyRuleEventContent};
use crate::events::{EventContent, StateEventContent, StateEventType};
@ -30,16 +29,6 @@ impl EventContent for PossiblyRedactedPolicyRuleRoomEventContent {
fn event_type(&self) -> Self::EventType {
StateEventType::PolicyRuleRoom
}
fn from_parts(event_type: &str, content: &RawJsonValue) -> serde_json::Result<Self> {
if event_type != "m.policy.rule.room" {
return Err(::serde::de::Error::custom(format!(
"expected event type `m.policy.rule.room`, found `{event_type}`",
)));
}
serde_json::from_str(content.get())
}
}
impl StateEventContent for PossiblyRedactedPolicyRuleRoomEventContent {

View File

@ -4,7 +4,6 @@
use ruma_macros::EventContent;
use serde::{Deserialize, Serialize};
use serde_json::value::RawValue as RawJsonValue;
use super::{PolicyRuleEventContent, PossiblyRedactedPolicyRuleEventContent};
use crate::events::{EventContent, StateEventContent, StateEventType};
@ -30,16 +29,6 @@ impl EventContent for PossiblyRedactedPolicyRuleServerEventContent {
fn event_type(&self) -> Self::EventType {
StateEventType::PolicyRuleServer
}
fn from_parts(event_type: &str, content: &RawJsonValue) -> serde_json::Result<Self> {
if event_type != "m.policy.rule.server" {
return Err(::serde::de::Error::custom(format!(
"expected event type `m.policy.rule.server`, found `{event_type}`",
)));
}
serde_json::from_str(content.get())
}
}
impl StateEventContent for PossiblyRedactedPolicyRuleServerEventContent {

View File

@ -4,7 +4,6 @@
use ruma_macros::EventContent;
use serde::{Deserialize, Serialize};
use serde_json::value::RawValue as RawJsonValue;
use super::{PolicyRuleEventContent, PossiblyRedactedPolicyRuleEventContent};
use crate::events::{EventContent, StateEventContent, StateEventType};
@ -30,16 +29,6 @@ impl EventContent for PossiblyRedactedPolicyRuleUserEventContent {
fn event_type(&self) -> Self::EventType {
StateEventType::PolicyRuleUser
}
fn from_parts(event_type: &str, content: &RawJsonValue) -> serde_json::Result<Self> {
if event_type != "m.policy.rule.user" {
return Err(::serde::de::Error::custom(format!(
"expected event type `m.policy.rule.user`, found `{event_type}`",
)));
}
serde_json::from_str(content.get())
}
}
impl StateEventContent for PossiblyRedactedPolicyRuleUserEventContent {

View File

@ -2,7 +2,6 @@
use ruma_macros::EventContent;
use serde::{Deserialize, Serialize};
use serde_json::value::RawValue as RawJsonValue;
use crate::{
events::{
@ -83,16 +82,6 @@ impl EventContent for RedactedRoomAliasesEventContent {
fn event_type(&self) -> StateEventType {
StateEventType::RoomAliases
}
fn from_parts(event_type: &str, content: &RawJsonValue) -> serde_json::Result<Self> {
if event_type != "m.room.aliases" {
return Err(::serde::de::Error::custom(format!(
"expected event type `m.room.aliases`, found `{event_type}`",
)));
}
serde_json::from_str(content.get())
}
}
impl StateEventContent for RedactedRoomAliasesEventContent {

View File

@ -7,7 +7,6 @@ use std::collections::BTreeMap;
use js_int::Int;
use ruma_macros::EventContent;
use serde::{Deserialize, Serialize};
use serde_json::value::RawValue as RawJsonValue;
use crate::{
events::{
@ -243,16 +242,6 @@ impl EventContent for RedactedRoomMemberEventContent {
fn event_type(&self) -> StateEventType {
StateEventType::RoomMember
}
fn from_parts(event_type: &str, content: &RawJsonValue) -> serde_json::Result<Self> {
if event_type != "m.room.member" {
return Err(::serde::de::Error::custom(format!(
"expected event type `m.room.member`, found `{event_type}`",
)));
}
serde_json::from_str(content.get())
}
}
impl StateEventContent for RedactedRoomMemberEventContent {

View File

@ -141,11 +141,8 @@ mod tests {
}))
.unwrap();
let content = <SecretStorageKeyEventContent as EventContentFromType>::from_parts(
"m.secret_storage.key.test",
&json,
)
.unwrap();
let content =
SecretStorageKeyEventContent::from_parts("m.secret_storage.key.test", &json).unwrap();
assert_eq!(content.name.unwrap(), "my_key");
assert_matches!(content.passphrase, None);
@ -169,11 +166,8 @@ mod tests {
}))
.unwrap();
let content = <SecretStorageKeyEventContent as EventContentFromType>::from_parts(
"m.secret_storage.key.test",
&json,
)
.unwrap();
let content =
SecretStorageKeyEventContent::from_parts("m.secret_storage.key.test", &json).unwrap();
assert!(content.name.is_none());
assert_matches!(content.passphrase, None);
@ -233,11 +227,8 @@ mod tests {
}))
.unwrap();
let content = <SecretStorageKeyEventContent as EventContentFromType>::from_parts(
"m.secret_storage.key.test",
&json,
)
.unwrap();
let content =
SecretStorageKeyEventContent::from_parts("m.secret_storage.key.test", &json).unwrap();
assert_eq!(content.name.unwrap(), "my_key");
let passphrase = content.passphrase.unwrap();

View File

@ -8,8 +8,8 @@ use ruma_common::{
redaction::RoomRedactionEventContent,
},
AnyMessageLikeEvent, AnySyncMessageLikeEvent, AnySyncStateEvent, AnySyncTimelineEvent,
AnyTimelineEvent, EventContent, MessageLikeEvent, RedactContent, SyncMessageLikeEvent,
SyncStateEvent,
AnyTimelineEvent, EventContentFromType, MessageLikeEvent, RedactContent,
SyncMessageLikeEvent, SyncStateEvent,
},
RoomVersionId,
};

View File

@ -2,7 +2,7 @@
use proc_macro2::{Span, TokenStream};
use quote::quote;
use syn::{Data, DataStruct, DeriveInput, Field, Fields, FieldsNamed};
use syn::{parse_quote, Data, DataStruct, DeriveInput, Field, Fields, FieldsNamed};
use super::{
event_parse::{to_kind_variation, EventKind, EventKindVariation},
@ -109,31 +109,13 @@ fn expand_deserialize_event(
.iter()
.map(|field| {
let name = field.ident.as_ref().unwrap();
Ok(if name == "content" {
if is_generic && var.is_redacted() {
quote! {
let content = {
let json = content.ok_or_else(
|| #serde::de::Error::missing_field("content"),
)?;
C::from_parts(&event_type, &json)
.map_err(#serde::de::Error::custom)?
};
}
} else if is_generic {
quote! {
let content = {
let json = content
.ok_or_else(|| #serde::de::Error::missing_field("content"))?;
C::from_parts(&event_type, &json).map_err(#serde::de::Error::custom)?
};
}
} else {
quote! {
let content = content.ok_or_else(
|| #serde::de::Error::missing_field("content"),
)?;
}
Ok(if name == "content" && is_generic {
quote! {
let content = {
let json = content
.ok_or_else(|| #serde::de::Error::missing_field("content"))?;
C::from_parts(&event_type, &json).map_err(#serde::de::Error::custom)?
};
}
} else if name == "unsigned" && !var.is_redacted() {
quote! {
@ -170,6 +152,17 @@ fn expand_deserialize_event(
} else {
quote! {}
};
let where_clause = if is_generic {
let predicate = parse_quote! { C: #ruma_common::events::EventContentFromType };
if let Some(mut where_clause) = where_clause.cloned() {
where_clause.predicates.push(predicate);
Some(where_clause)
} else {
Some(parse_quote! { where #predicate })
}
} else {
where_clause.cloned()
};
Ok(quote! {
#[automatically_derived]

View File

@ -894,27 +894,6 @@ fn generate_event_content_impl<'a>(
let event_types = aliases.iter().chain([event_type]);
let from_parts_fn_impl = if type_suffix_data.is_some() {
quote! {
<Self as #ruma_common::events::EventContentFromType>::from_parts(ev_type, content)
}
} else {
let event_types = event_types.clone();
let event_types = quote! {
[#(#event_types,)*]
};
quote! {
if !#event_types.contains(&ev_type) {
return ::std::result::Result::Err(#serde::de::Error::custom(
::std::format!("expected event type as one of `{:?}`, found `{}`", #event_types, ev_type)
));
}
#serde_json::from_str(content.get())
}
};
let event_content_from_type_impl = type_suffix_data.map(|(_, type_fragment_field)| {
let type_prefixes = event_types.map(|ev_type| {
ev_type
@ -971,13 +950,6 @@ fn generate_event_content_impl<'a>(
fn event_type(&self) -> Self::EventType {
#event_type_fn_impl
}
fn from_parts(
ev_type: &::std::primitive::str,
content: &#serde_json::value::RawValue,
) -> #serde_json::Result<Self> {
#from_parts_fn_impl
}
}
#event_content_from_type_impl

View File

@ -1,6 +1,6 @@
//! Implementation of event enum and event content enum macros.
use std::{fmt, iter::zip};
use std::fmt;
use proc_macro2::{Span, TokenStream};
use quote::{format_ident, quote, IdentFragment, ToTokens};
@ -307,7 +307,6 @@ fn expand_content_enum(
ruma_common: &TokenStream,
) -> syn::Result<TokenStream> {
let serde = quote! { #ruma_common::exports::serde };
let serde_json = quote! { #ruma_common::exports::serde_json };
let ident = kind.to_content_enum();
@ -320,36 +319,6 @@ fn expand_content_enum(
Ok(to_event_content_path(kind, stable_name, &event.ev_path, None))
})
.collect::<syn::Result<_>>()?;
let event_type_match_arms: TokenStream = zip(zip(events, variants), &content)
.map(|((event, variant), ev_content)| {
let variant_attrs = {
let attrs = &variant.attrs;
quote! { #(#attrs)* }
};
let variant_ctor = variant.ctor(quote! { Self });
let ev_types = event.aliases.iter().chain([&event.ev_type]);
let ev_types = if event.ev_type.value().ends_with(".*") {
let ev_types = ev_types.map(|ev_type| {
ev_type
.value()
.strip_suffix(".*")
.expect("aliases have already been checked to have the same suffix")
.to_owned()
});
quote! { _s if #(_s.starts_with(#ev_types))||* }
} else {
quote! { #(#ev_types)|* }
};
Ok(quote! {
#variant_attrs #ev_types => {
let content = #ev_content::from_parts(event_type, input)?;
::std::result::Result::Ok(#variant_ctor(content))
},
})
})
.collect::<syn::Result<_>>()?;
let variant_decls = variants.iter().map(|v| v.decl()).collect::<Vec<_>>();
let variant_arms = variants.iter().map(|v| v.match_arm(quote! { Self })).collect::<Vec<_>>();
@ -394,20 +363,6 @@ fn expand_content_enum(
Self::_Custom { event_type } => ::std::convert::From::from(&event_type.0[..]),
}
}
fn from_parts(
event_type: &::std::primitive::str,
input: &#serde_json::value::RawValue,
) -> #serde_json::Result<Self> {
match event_type {
#event_type_match_arms
ty => {
::std::result::Result::Ok(Self::_Custom {
event_type: crate::PrivOwnedStr(ty.into()),
})
}
}
}
}
#[automatically_derived]