events: Allow state_key to be empty in InitialStateEvent

This commit is contained in:
Jonas Platte 2021-02-06 15:15:57 +01:00
parent f2d9e5b019
commit 7846142690
No known key found for this signature in database
GPG Key ID: 7D261D771D915378
3 changed files with 56 additions and 12 deletions

View File

@ -2,7 +2,9 @@
use proc_macro2::{Span, TokenStream}; use proc_macro2::{Span, TokenStream};
use quote::quote; use quote::quote;
use syn::{Data, DataStruct, DeriveInput, Field, Fields, FieldsNamed, Ident}; use syn::{
Data, DataStruct, DeriveInput, Field, Fields, FieldsNamed, Ident, Meta, MetaList, NestedMeta,
};
use crate::{ use crate::{
event_parse::{to_kind_variation, EventKind, EventKindVariation}, event_parse::{to_kind_variation, EventKind, EventKindVariation},
@ -42,7 +44,7 @@ pub fn expand_event(input: DeriveInput) -> syn::Result<TokenStream> {
}; };
let serialize_impl = expand_serialize_event(&input, &var, &fields, &ruma_events); let serialize_impl = expand_serialize_event(&input, &var, &fields, &ruma_events);
let deserialize_impl = expand_deserialize_event(&input, &var, &fields, &ruma_events); let deserialize_impl = expand_deserialize_event(&input, &var, &fields, &ruma_events)?;
let conversion_impl = expand_from_into(&input, &kind, &var, &fields, &ruma_events); let conversion_impl = expand_from_into(&input, &kind, &var, &fields, &ruma_events);
let eq_impl = expand_eq_ord_event(&input, &fields); let eq_impl = expand_eq_ord_event(&input, &fields);
@ -133,7 +135,7 @@ fn expand_deserialize_event(
var: &EventKindVariation, var: &EventKindVariation,
fields: &[Field], fields: &[Field],
ruma_events: &TokenStream, ruma_events: &TokenStream,
) -> TokenStream { ) -> syn::Result<TokenStream> {
let js_int = quote! { #ruma_events::exports::js_int }; let js_int = quote! { #ruma_events::exports::js_int };
let serde = quote! { #ruma_events::exports::serde }; let serde = quote! { #ruma_events::exports::serde };
let serde_json = quote! { #ruma_events::exports::serde_json }; let serde_json = quote! { #ruma_events::exports::serde_json };
@ -181,7 +183,7 @@ fn expand_deserialize_event(
.iter() .iter()
.map(|field| { .map(|field| {
let name = field.ident.as_ref().unwrap(); let name = field.ident.as_ref().unwrap();
if name == "content" { Ok(if name == "content" {
if is_generic && var.is_redacted() { if is_generic && var.is_redacted() {
quote! { quote! {
let content = match C::has_deserialize_fields() { let content = match C::has_deserialize_fields() {
@ -245,6 +247,28 @@ fn expand_deserialize_event(
} }
} else if name == "unsigned" { } else if name == "unsigned" {
quote! { let unsigned = unsigned.unwrap_or_default(); } quote! { let unsigned = unsigned.unwrap_or_default(); }
} else {
let attrs: Vec<_> = field
.attrs
.iter()
.filter(|a| a.path.is_ident("ruma_event"))
.map(|a| a.parse_meta())
.collect::<syn::Result<_>>()?;
let has_default_attr = attrs.iter().any(|a| {
matches!(
a,
Meta::List(MetaList { nested, .. })
if nested.iter().any(|n| {
matches!(n, NestedMeta::Meta(Meta::Path(p)) if p.is_ident("default"))
})
)
});
if has_default_attr {
quote! {
let #name = #name.unwrap_or_default();
}
} else { } else {
quote! { quote! {
let #name = #name.ok_or_else(|| { let #name = #name.ok_or_else(|| {
@ -253,7 +277,8 @@ fn expand_deserialize_event(
} }
} }
}) })
.collect(); })
.collect::<syn::Result<_>>()?;
let field_names: Vec<_> = fields.iter().flat_map(|f| &f.ident).collect(); let field_names: Vec<_> = fields.iter().flat_map(|f| &f.ident).collect();
@ -269,7 +294,7 @@ fn expand_deserialize_event(
quote! {} quote! {}
}; };
quote! { Ok(quote! {
#[automatically_derived] #[automatically_derived]
impl #deserialize_impl_gen #serde::de::Deserialize<'de> for #ident #ty_gen #where_clause { impl #deserialize_impl_gen #serde::de::Deserialize<'de> for #ident #ty_gen #where_clause {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
@ -350,7 +375,7 @@ fn expand_deserialize_event(
deserializer.deserialize_map(EventVisitor(#deserialize_phantom_type)) deserializer.deserialize_map(EventVisitor(#deserialize_phantom_type))
} }
} }
} })
} }
fn expand_from_into( fn expand_from_into(

View File

@ -226,6 +226,9 @@ pub struct InitialStateEvent<C: StateEventContent> {
/// ///
/// This is often an empty string, but some events send a `UserId` to show /// This is often an empty string, but some events send a `UserId` to show
/// which user the event affects. /// which user the event affects.
///
/// Defaults to the empty string.
#[ruma_event(default)]
pub state_key: String, pub state_key: String,
} }

View File

@ -0,0 +1,16 @@
use matches::assert_matches;
use ruma_events::{AnyInitialStateEvent, InitialStateEvent};
use serde_json::json;
#[test]
fn deserialize_initial_state_event() {
assert_matches!(
serde_json::from_value(json!({
"type": "m.room.name",
"content": { "name": "foo" }
}))
.unwrap(),
AnyInitialStateEvent::RoomName(InitialStateEvent { content, state_key})
if content.name() == Some("foo") && state_key.is_empty()
);
}