events: Derive / implement StaticEventContent for all relevant types

This commit is contained in:
Jonas Platte 2021-08-11 20:30:17 +02:00
parent a30279b83f
commit 9445e8756a
No known key found for this signature in database
GPG Key ID: CC154DE0E30B7C67
4 changed files with 53 additions and 2 deletions

View File

@ -149,12 +149,16 @@ pub fn expand_event_content(
.transpose()?;
let event_content_impl = generate_event_content_impl(&input.ident, event_type, ruma_events);
let static_event_content_impl = event_kind.map(|k| {
generate_static_event_content_impl(&input.ident, k, false, event_type, ruma_events)
});
let marker_trait_impl =
event_kind.map(|k| generate_marker_trait_impl(k, &input.ident, ruma_events)).transpose()?;
Ok(quote! {
#redacted_event_content
#event_content_impl
#static_event_content_impl
#marker_trait_impl
})
}
@ -251,7 +255,7 @@ fn generate_redacted_event_content(
let redacted_event_content =
generate_event_content_impl(&redacted_ident, event_type, ruma_events);
let redacted_event_content_derive = match event_kind {
let marker_trait_impl = match event_kind {
Some(EventKind::Message) => quote! {
#[automatically_derived]
impl #ruma_events::RedactedMessageEventContent for #redacted_ident {}
@ -263,6 +267,10 @@ fn generate_redacted_event_content(
_ => TokenStream::new(),
};
let static_event_content_impl = event_kind.map(|k| {
generate_static_event_content_impl(&redacted_ident, k, true, event_type, ruma_events)
});
Ok(quote! {
// this is the non redacted event content's impl
#[automatically_derived]
@ -306,7 +314,8 @@ fn generate_redacted_event_content(
}
}
#redacted_event_content_derive
#static_event_content_impl
#marker_trait_impl
})
}
@ -368,6 +377,33 @@ fn generate_event_content_impl(
}
}
fn generate_static_event_content_impl(
ident: &Ident,
event_kind: &EventKind,
redacted: bool,
event_type: &LitStr,
ruma_events: &TokenStream,
) -> TokenStream {
let event_kind = match event_kind {
EventKind::GlobalAccountData => quote! { GlobalAccountData },
EventKind::RoomAccountData => quote! { RoomAccountData },
EventKind::Ephemeral => quote! { EphemeralRoomData },
EventKind::Message => quote! { Message { redacted: #redacted } },
EventKind::State => quote! { State { redacted: #redacted } },
EventKind::ToDevice => quote! { ToDevice },
EventKind::Redaction | EventKind::Presence | EventKind::Decrypted => {
unreachable!("not a valid event content kind")
}
};
quote! {
impl #ruma_events::StaticEventContent for #ident {
const KIND: #ruma_events::EventKind = #ruma_events::EventKind::#event_kind;
const TYPE: &'static ::std::primitive::str = #event_type;
}
}
}
fn needs_redacted(input: &[MetaAttrs], event_kind: Option<&EventKind>) -> bool {
// `is_custom` means that the content struct does not need a generated
// redacted struct also. If no `custom_redacted` attrs are found the content

View File

@ -14,6 +14,11 @@ Breaking changes:
* It doesn't have the `relates_to` field `EncryptedEventContent` has
* Upgrade dependencies
Improvements:
* Add the `StaticEventContent` trait for abstracting over event content struct
types (with a type known at compile-time)
# 0.24.0
Yanked, was released too early missing another important breaking change.

View File

@ -407,6 +407,9 @@ pub enum EventKind {
/// To-device event kind.
ToDevice,
/// Presence event kind.
Presence,
}
/// `HasDeserializeFields` is used in the code generated by the `Event` derive

View File

@ -8,6 +8,8 @@ use ruma_events_macros::{Event, EventContent};
use ruma_identifiers::{MxcUri, UserId};
use serde::{Deserialize, Serialize};
use crate::{EventKind, StaticEventContent};
/// Presence event.
#[derive(Clone, Debug, Event)]
#[allow(clippy::exhaustive_structs)]
@ -71,6 +73,11 @@ impl PresenceEventContent {
}
}
impl StaticEventContent for PresenceEventContent {
const KIND: EventKind = EventKind::Presence;
const TYPE: &'static str = "m.presence";
}
#[cfg(test)]
mod tests {
use js_int::uint;