events: Add accessors for state events' original or redacted content
This commit is contained in:
parent
284b797e05
commit
baaf73adbc
@ -62,6 +62,7 @@ Improvements:
|
|||||||
* `Ruleset::set_actions` to change the actions of push rules
|
* `Ruleset::set_actions` to change the actions of push rules
|
||||||
* Add support for bundled reference relations (MSC3267 / Matrix 1.5)
|
* Add support for bundled reference relations (MSC3267 / Matrix 1.5)
|
||||||
* Add the `formatted` field on `KeyVerificationRequestEventContent` (Matrix 1.5)
|
* Add the `formatted` field on `KeyVerificationRequestEventContent` (Matrix 1.5)
|
||||||
|
* Add `content` accessors for `Any*StateEvent` enums
|
||||||
|
|
||||||
# 0.10.5
|
# 0.10.5
|
||||||
|
|
||||||
|
@ -417,6 +417,28 @@ pub struct DecryptedMegolmV1Event<C: MessageLikeEventContent> {
|
|||||||
pub room_id: OwnedRoomId,
|
pub room_id: OwnedRoomId,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A possibly-redacted state event content.
|
||||||
|
///
|
||||||
|
/// A non-redacted content also contains the `prev_content` from the unsigned event data.
|
||||||
|
#[allow(clippy::exhaustive_enums)]
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub enum FullStateEventContent<C: StateEventContent + RedactContent>
|
||||||
|
where
|
||||||
|
C::Redacted: RedactedStateEventContent,
|
||||||
|
{
|
||||||
|
/// Original, unredacted content of the event.
|
||||||
|
Original {
|
||||||
|
/// Current content of the room state.
|
||||||
|
content: C,
|
||||||
|
|
||||||
|
/// Previous content of the room state.
|
||||||
|
prev_content: Option<C>,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// Redacted content of the event.
|
||||||
|
Redacted(C::Redacted),
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! impl_possibly_redacted_event {
|
macro_rules! impl_possibly_redacted_event {
|
||||||
(
|
(
|
||||||
$ty:ident ( $content_trait:ident, $redacted_content_trait:ident, $event_type:ident )
|
$ty:ident ( $content_trait:ident, $redacted_content_trait:ident, $event_type:ident )
|
||||||
|
@ -87,6 +87,7 @@ pub fn expand_event_enums(input: &EventEnumDecl) -> syn::Result<TokenStream> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if matches!(kind, EventKind::State) {
|
if matches!(kind, EventKind::State) {
|
||||||
|
res.extend(expand_full_content_enum(kind, events, docs, attrs, variants, ruma_common));
|
||||||
res.extend(
|
res.extend(
|
||||||
expand_event_enum(kind, V::Stripped, events, docs, attrs, variants, ruma_common)
|
expand_event_enum(kind, V::Stripped, events, docs, attrs, variants, ruma_common)
|
||||||
.unwrap_or_else(syn::Error::into_compile_error),
|
.unwrap_or_else(syn::Error::into_compile_error),
|
||||||
@ -125,7 +126,8 @@ fn expand_event_enum(
|
|||||||
let custom_ty = format_ident!("Custom{}Content", kind);
|
let custom_ty = format_ident!("Custom{}Content", kind);
|
||||||
|
|
||||||
let deserialize_impl = expand_deserialize_impl(kind, var, events, ruma_common)?;
|
let deserialize_impl = expand_deserialize_impl(kind, var, events, ruma_common)?;
|
||||||
let field_accessor_impl = expand_accessor_methods(kind, var, variants, ruma_common)?;
|
let field_accessor_impl =
|
||||||
|
expand_accessor_methods(kind, var, variants, &event_struct, ruma_common)?;
|
||||||
let from_impl = expand_from_impl(&ident, &content, variants);
|
let from_impl = expand_from_impl(&ident, &content, variants);
|
||||||
|
|
||||||
Ok(quote! {
|
Ok(quote! {
|
||||||
@ -419,10 +421,51 @@ fn expand_content_enum(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a full content enum from `EventEnumInput`.
|
||||||
|
fn expand_full_content_enum(
|
||||||
|
kind: EventKind,
|
||||||
|
events: &[EventEnumEntry],
|
||||||
|
docs: &[TokenStream],
|
||||||
|
attrs: &[Attribute],
|
||||||
|
variants: &[EventEnumVariant],
|
||||||
|
ruma_common: &TokenStream,
|
||||||
|
) -> syn::Result<TokenStream> {
|
||||||
|
let ident = kind.to_full_content_enum();
|
||||||
|
|
||||||
|
let content: Vec<_> = events
|
||||||
|
.iter()
|
||||||
|
.map(|event| {
|
||||||
|
let stable_name = event.stable_name()?;
|
||||||
|
Ok(to_event_content_path(kind, stable_name, &event.ev_path, None))
|
||||||
|
})
|
||||||
|
.collect::<syn::Result<_>>()?;
|
||||||
|
|
||||||
|
let variant_decls = variants.iter().map(|v| v.decl()).collect::<Vec<_>>();
|
||||||
|
|
||||||
|
Ok(quote! {
|
||||||
|
#( #attrs )*
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
#[allow(clippy::large_enum_variant)]
|
||||||
|
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
|
||||||
|
pub enum #ident {
|
||||||
|
#(
|
||||||
|
#docs
|
||||||
|
#variant_decls(#ruma_common::events::FullStateEventContent<#content>),
|
||||||
|
)*
|
||||||
|
#[doc(hidden)]
|
||||||
|
_Custom {
|
||||||
|
event_type: crate::PrivOwnedStr,
|
||||||
|
redacted: bool,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn expand_accessor_methods(
|
fn expand_accessor_methods(
|
||||||
kind: EventKind,
|
kind: EventKind,
|
||||||
var: EventEnumVariation,
|
var: EventEnumVariation,
|
||||||
variants: &[EventEnumVariant],
|
variants: &[EventEnumVariant],
|
||||||
|
event_struct: &Ident,
|
||||||
ruma_common: &TokenStream,
|
ruma_common: &TokenStream,
|
||||||
) -> syn::Result<TokenStream> {
|
) -> syn::Result<TokenStream> {
|
||||||
let ident = kind.to_event_enum_ident(var.into())?;
|
let ident = kind.to_event_enum_ident(var.into())?;
|
||||||
@ -450,7 +493,7 @@ fn expand_accessor_methods(
|
|||||||
let content_enum = kind.to_content_enum();
|
let content_enum = kind.to_content_enum();
|
||||||
let content_variants: Vec<_> = variants.iter().map(|v| v.ctor(&content_enum)).collect();
|
let content_variants: Vec<_> = variants.iter().map(|v| v.ctor(&content_enum)).collect();
|
||||||
let content_accessor = if maybe_redacted {
|
let content_accessor = if maybe_redacted {
|
||||||
quote! {
|
let mut accessors = quote! {
|
||||||
/// Returns the content for this event if it is not redacted, or `None` if it is.
|
/// Returns the content for this event if it is not redacted, or `None` if it is.
|
||||||
pub fn original_content(&self) -> Option<#content_enum> {
|
pub fn original_content(&self) -> Option<#content_enum> {
|
||||||
match self {
|
match self {
|
||||||
@ -474,7 +517,66 @@ fn expand_accessor_methods(
|
|||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if kind == EventKind::State {
|
||||||
|
let full_content_enum = kind.to_full_content_enum();
|
||||||
|
let full_content_variants: Vec<_> =
|
||||||
|
variants.iter().map(|v| v.ctor(&full_content_enum)).collect();
|
||||||
|
|
||||||
|
accessors = quote! {
|
||||||
|
#accessors
|
||||||
|
|
||||||
|
/// Returns the content of this state event.
|
||||||
|
pub fn content(&self) -> #full_content_enum {
|
||||||
|
match self {
|
||||||
|
#(
|
||||||
|
#self_variants(event) => match event {
|
||||||
|
#ruma_common::events::#event_struct::Original(ev) => #full_content_variants(
|
||||||
|
#ruma_common::events::FullStateEventContent::Original {
|
||||||
|
content: ev.content.clone(),
|
||||||
|
prev_content: ev.unsigned.prev_content.clone()
|
||||||
|
}
|
||||||
|
),
|
||||||
|
#ruma_common::events::#event_struct::Redacted(ev) => #full_content_variants(
|
||||||
|
#ruma_common::events::FullStateEventContent::Redacted(
|
||||||
|
ev.content.clone()
|
||||||
|
)
|
||||||
|
),
|
||||||
|
}
|
||||||
|
)*
|
||||||
|
Self::_Custom(event) => match event {
|
||||||
|
#ruma_common::events::#event_struct::Original(ev) => {
|
||||||
|
#full_content_enum::_Custom {
|
||||||
|
event_type: crate::PrivOwnedStr(
|
||||||
|
::std::string::ToString::to_string(
|
||||||
|
&#ruma_common::events::EventContent::event_type(
|
||||||
|
&ev.content,
|
||||||
|
),
|
||||||
|
).into_boxed_str(),
|
||||||
|
),
|
||||||
|
redacted: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ruma_common::events::#event_struct::Redacted(ev) => {
|
||||||
|
#full_content_enum::_Custom {
|
||||||
|
event_type: crate::PrivOwnedStr(
|
||||||
|
::std::string::ToString::to_string(
|
||||||
|
&#ruma_common::events::EventContent::event_type(
|
||||||
|
&ev.content,
|
||||||
|
),
|
||||||
|
).into_boxed_str(),
|
||||||
|
),
|
||||||
|
redacted: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
accessors
|
||||||
} else {
|
} else {
|
||||||
quote! {
|
quote! {
|
||||||
/// Returns the content for this event.
|
/// Returns the content for this event.
|
||||||
|
@ -147,6 +147,11 @@ impl EventKind {
|
|||||||
pub fn to_content_enum(self) -> Ident {
|
pub fn to_content_enum(self) -> Ident {
|
||||||
format_ident!("Any{}Content", self)
|
format_ident!("Any{}Content", self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// `AnyFull[kind]EventContent`
|
||||||
|
pub fn to_full_content_enum(self) -> Ident {
|
||||||
|
format_ident!("AnyFull{}Content", self)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Parse for EventKind {
|
impl Parse for EventKind {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user