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