Move raw mod into FromRaw derive
				
					
				
			This commit is contained in:
		
							parent
							
								
									1a9b0f3e8b
								
							
						
					
					
						commit
						f0c94958fa
					
				| @ -15,6 +15,16 @@ pub fn expand_from_raw(input: DeriveInput) -> syn::Result<TokenStream> { | |||||||
|     }; |     }; | ||||||
|     let ident = &input.ident; |     let ident = &input.ident; | ||||||
| 
 | 
 | ||||||
|  |     let raw_content = { | ||||||
|  |         let fields = fields.iter(); | ||||||
|  |         quote! { | ||||||
|  |             #[derive(Clone, Debug, serde::Deserialize)] | ||||||
|  |             pub struct #ident { | ||||||
|  |                 #(#fields),* | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|     let init_list = fields.iter().map(|field| { |     let init_list = fields.iter().map(|field| { | ||||||
|         let field_ident = field.ident.as_ref().unwrap(); |         let field_ident = field.ident.as_ref().unwrap(); | ||||||
|         let field_span = field.span(); |         let field_span = field.span(); | ||||||
| @ -44,5 +54,11 @@ pub fn expand_from_raw(input: DeriveInput) -> syn::Result<TokenStream> { | |||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|  |         pub(crate) mod raw { | ||||||
|  |             use super::*; | ||||||
|  | 
 | ||||||
|  |             #raw_content | ||||||
|  |         } | ||||||
|     }) |     }) | ||||||
| } | } | ||||||
|  | |||||||
| @ -3,12 +3,11 @@ | |||||||
| #![allow(dead_code)] | #![allow(dead_code)] | ||||||
| 
 | 
 | ||||||
| use proc_macro2::{Span, TokenStream}; | use proc_macro2::{Span, TokenStream}; | ||||||
| use quote::{format_ident, quote, quote_spanned, ToTokens}; | use quote::{format_ident, quote, ToTokens}; | ||||||
| use syn::{ | use syn::{ | ||||||
|     parse::{self, Parse, ParseStream}, |     parse::{self, Parse, ParseStream}, | ||||||
|     parse_quote, |     parse_quote, | ||||||
|     punctuated::Punctuated, |     punctuated::Punctuated, | ||||||
|     spanned::Spanned, |  | ||||||
|     Attribute, Field, Ident, LitStr, Token, |     Attribute, Field, Ident, LitStr, Token, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| @ -87,10 +86,9 @@ impl ToTokens for RumaEvent { | |||||||
| 
 | 
 | ||||||
|         let content = match &self.content { |         let content = match &self.content { | ||||||
|             Content::Struct(fields) => { |             Content::Struct(fields) => { | ||||||
|                 // TODO remove serde::Deserialize when this macro actually generates generic events
 |  | ||||||
|                 quote! { |                 quote! { | ||||||
|                     #[doc = #content_docstring] |                     #[doc = #content_docstring] | ||||||
|                     #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)] |                     #[derive(Clone, Debug, serde::Serialize, ::ruma_events_macros::FromRaw)] | ||||||
|                     pub struct #content_name { |                     pub struct #content_name { | ||||||
|                         #(#fields),* |                         #(#fields),* | ||||||
|                     } |                     } | ||||||
| @ -107,67 +105,9 @@ impl ToTokens for RumaEvent { | |||||||
|             } |             } | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|         let raw_content = match &self.content { |  | ||||||
|             Content::Struct(fields) => { |  | ||||||
|                 quote! { |  | ||||||
|                     #[doc = #content_docstring] |  | ||||||
|                     #[derive(Clone, Debug, serde::Deserialize)] |  | ||||||
|                     pub struct #content_name { |  | ||||||
|                         #(#fields),* |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|             Content::Typedef(_) => TokenStream::new(), |  | ||||||
|         }; |  | ||||||
| 
 |  | ||||||
|         let impl_event_result_compatible_for_content = |  | ||||||
|             if let Content::Struct(content_fields) = &self.content { |  | ||||||
|                 let mut content_field_values: Vec<TokenStream> = |  | ||||||
|                     Vec::with_capacity(content_fields.len()); |  | ||||||
| 
 |  | ||||||
|                 for content_field in content_fields { |  | ||||||
|                     let content_field_ident = content_field.ident.clone().unwrap(); |  | ||||||
|                     let span = content_field.span(); |  | ||||||
| 
 |  | ||||||
|                     let token_stream = quote_spanned! {span=> |  | ||||||
|                         #content_field_ident: raw.#content_field_ident, |  | ||||||
|                     }; |  | ||||||
| 
 |  | ||||||
|                     content_field_values.push(token_stream); |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 quote! { |  | ||||||
|                     impl ::ruma_events::FromRaw for #content_name { |  | ||||||
|                         type Raw = raw::#content_name; |  | ||||||
| 
 |  | ||||||
|                         fn from_raw( |  | ||||||
|                             raw: raw::#content_name |  | ||||||
|                         ) -> Self { |  | ||||||
|                             Self { |  | ||||||
|                                 #(#content_field_values)* |  | ||||||
|                             } |  | ||||||
|                         } |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } else { |  | ||||||
|                 TokenStream::new() |  | ||||||
|             }; |  | ||||||
| 
 |  | ||||||
|         // let event_type_name = self.event_type.value();
 |         // let event_type_name = self.event_type.value();
 | ||||||
|         let output = quote!( |  | ||||||
|             #content |  | ||||||
| 
 | 
 | ||||||
|             #impl_event_result_compatible_for_content |         content.to_tokens(tokens); | ||||||
| 
 |  | ||||||
|             /// "Raw" versions of the event and its content which implement `serde::Deserialize`.
 |  | ||||||
|             pub(crate) mod raw { |  | ||||||
|                 use super::*; |  | ||||||
| 
 |  | ||||||
|                 #raw_content |  | ||||||
|             } |  | ||||||
|         ); |  | ||||||
| 
 |  | ||||||
|         output.to_tokens(tokens); |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										10
									
								
								src/lib.rs
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								src/lib.rs
									
									
									
									
									
								
							| @ -120,10 +120,11 @@ use std::fmt::Debug; | |||||||
| 
 | 
 | ||||||
| use js_int::Int; | use js_int::Int; | ||||||
| use serde::{Deserialize, Serialize}; | use serde::{Deserialize, Serialize}; | ||||||
|  | use serde_json::value::RawValue as RawJsonValue; | ||||||
| 
 | 
 | ||||||
| // use self::room::redaction::RedactionEvent;
 | // use self::room::redaction::RedactionEvent;
 | ||||||
| 
 | 
 | ||||||
| pub use self::custom::{CustomEvent, CustomRoomEvent, CustomStateEvent}; | // pub use self::custom::{CustomEvent, CustomRoomEvent, CustomStateEvent};
 | ||||||
| 
 | 
 | ||||||
| #[deprecated = "Use ruma_serde::empty::Empty directly instead."] | #[deprecated = "Use ruma_serde::empty::Empty directly instead."] | ||||||
| pub use ruma_serde::empty::Empty; | pub use ruma_serde::empty::Empty; | ||||||
| @ -141,7 +142,7 @@ pub mod util; | |||||||
| extern crate self as ruma_events; | extern crate self as ruma_events; | ||||||
| 
 | 
 | ||||||
| pub mod call; | pub mod call; | ||||||
| pub mod custom; | // pub mod custom;
 | ||||||
| /// Enums for heterogeneous collections of events.
 | /// Enums for heterogeneous collections of events.
 | ||||||
| // pub mod collections {
 | // pub mod collections {
 | ||||||
| //     pub mod all;
 | //     pub mod all;
 | ||||||
| @ -217,10 +218,7 @@ impl UnsignedData { | |||||||
| /// Implementing this trait allows content types to be serialized as well as deserialized.
 | /// Implementing this trait allows content types to be serialized as well as deserialized.
 | ||||||
| pub trait EventContent: Sized + Serialize { | pub trait EventContent: Sized + Serialize { | ||||||
|     /// Constructs the given event content.
 |     /// Constructs the given event content.
 | ||||||
|     fn from_parts( |     fn from_parts(event_type: &str, content: Box<RawJsonValue>) -> Result<Self, InvalidEvent>; | ||||||
|         event_type: &str, |  | ||||||
|         content: &serde_json::value::RawValue, |  | ||||||
|     ) -> Result<Self, InvalidEvent>; |  | ||||||
| 
 | 
 | ||||||
|     /// A matrix event identifier, like `m.room.message`.
 |     /// A matrix event identifier, like `m.room.message`.
 | ||||||
|     fn event_type(&self) -> &str; |     fn event_type(&self) -> &str; | ||||||
|  | |||||||
| @ -6,7 +6,7 @@ use serde_json::value::RawValue as RawJsonValue; | |||||||
| 
 | 
 | ||||||
| use crate::{ | use crate::{ | ||||||
|     error::{InvalidEvent, InvalidEventKind}, |     error::{InvalidEvent, InvalidEventKind}, | ||||||
|     EventContent, RoomEventContent, StateEventContent, |     EventContent, EventJson, RoomEventContent, StateEventContent, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| ruma_event! { | ruma_event! { | ||||||
| @ -26,17 +26,16 @@ impl EventContent for AliasesEventContent { | |||||||
|         "m.room.aliases" |         "m.room.aliases" | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn from_parts(event_type: &str, content: &RawJsonValue) -> Result<Self, InvalidEvent> { |     fn from_parts(event_type: &str, content: Box<RawJsonValue>) -> Result<Self, InvalidEvent> { | ||||||
|         if event_type != "m.room.aliases" { |         if event_type != "m.room.aliases" { | ||||||
|             return Err(InvalidEvent { |             return Err(InvalidEvent { | ||||||
|                 kind: InvalidEventKind::Deserialization, |                 kind: InvalidEventKind::Deserialization, | ||||||
|                 message: format!("expected `m.room.aliases` found {}", event_type), |                 message: format!("expected `m.room.aliases` found {}", event_type), | ||||||
|             }); |             }); | ||||||
|         } |         } | ||||||
|         serde_json::from_str::<AliasesEventContent>(content.get()).map_err(|e| InvalidEvent { | 
 | ||||||
|             kind: InvalidEventKind::Deserialization, |         let ev_json = EventJson::from(content); | ||||||
|             message: e.to_string(), |         ev_json.deserialize() | ||||||
|         }) |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -6,7 +6,7 @@ use serde_json::value::RawValue as RawJsonValue; | |||||||
| use super::ImageInfo; | use super::ImageInfo; | ||||||
| use crate::{ | use crate::{ | ||||||
|     error::{InvalidEvent, InvalidEventKind}, |     error::{InvalidEvent, InvalidEventKind}, | ||||||
|     EventContent, RoomEventContent, StateEventContent, |     EventContent, EventJson, RoomEventContent, StateEventContent, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| ruma_event! { | ruma_event! { | ||||||
| @ -33,17 +33,16 @@ impl EventContent for AvatarEventContent { | |||||||
|         "m.room.avatar" |         "m.room.avatar" | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn from_parts(event_type: &str, content: &RawJsonValue) -> Result<Self, InvalidEvent> { |     fn from_parts(event_type: &str, content: Box<RawJsonValue>) -> Result<Self, InvalidEvent> { | ||||||
|         if event_type != "m.room.avatar" { |         if event_type != "m.room.avatar" { | ||||||
|             return Err(InvalidEvent { |             return Err(InvalidEvent { | ||||||
|                 kind: InvalidEventKind::Deserialization, |                 kind: InvalidEventKind::Deserialization, | ||||||
|                 message: format!("expected `m.room.avatar` found {}", event_type), |                 message: format!("expected `m.room.avatar` found {}", event_type), | ||||||
|             }); |             }); | ||||||
|         } |         } | ||||||
|         serde_json::from_str::<AvatarEventContent>(content.get()).map_err(|e| InvalidEvent { | 
 | ||||||
|             kind: InvalidEventKind::Deserialization, |         let ev_json = EventJson::from(content); | ||||||
|             message: e.to_string(), |         ev_json.deserialize() | ||||||
|         }) |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -115,10 +115,10 @@ impl EventContent for AnyStateEventContent { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn from_parts(event_type: &str, content: &RawJsonValue) -> Result<Self, InvalidEvent> { |     fn from_parts(event_type: &str, content: Box<RawJsonValue>) -> Result<Self, InvalidEvent> { | ||||||
|         fn deserialize_variant<T: StateEventContent>( |         fn deserialize_variant<T: StateEventContent>( | ||||||
|             ev_type: &str, |             ev_type: &str, | ||||||
|             input: &RawJsonValue, |             input: Box<RawJsonValue>, | ||||||
|             variant: fn(T) -> AnyStateEventContent, |             variant: fn(T) -> AnyStateEventContent, | ||||||
|         ) -> Result<AnyStateEventContent, InvalidEvent> { |         ) -> Result<AnyStateEventContent, InvalidEvent> { | ||||||
|             let content = T::from_parts(ev_type, input)?; |             let content = T::from_parts(ev_type, input)?; | ||||||
| @ -278,7 +278,7 @@ impl<'de, C: StateEventContent> Visitor<'de> for StateEventVisitor<C> { | |||||||
|         let event_type = event_type.ok_or_else(|| de::Error::missing_field("type"))?; |         let event_type = event_type.ok_or_else(|| de::Error::missing_field("type"))?; | ||||||
| 
 | 
 | ||||||
|         let raw = content.ok_or_else(|| de::Error::missing_field("content"))?; |         let raw = content.ok_or_else(|| de::Error::missing_field("content"))?; | ||||||
|         let content = C::from_parts(&event_type, &raw).map_err(A::Error::custom)?; |         let content = C::from_parts(&event_type, raw).map_err(A::Error::custom)?; | ||||||
| 
 | 
 | ||||||
|         let event_id = event_id.ok_or_else(|| de::Error::missing_field("event_id"))?; |         let event_id = event_id.ok_or_else(|| de::Error::missing_field("event_id"))?; | ||||||
|         let sender = sender.ok_or_else(|| de::Error::missing_field("sender"))?; |         let sender = sender.ok_or_else(|| de::Error::missing_field("sender"))?; | ||||||
| @ -291,7 +291,7 @@ impl<'de, C: StateEventContent> Visitor<'de> for StateEventVisitor<C> { | |||||||
|         let state_key = state_key.ok_or_else(|| de::Error::missing_field("state_key"))?; |         let state_key = state_key.ok_or_else(|| de::Error::missing_field("state_key"))?; | ||||||
| 
 | 
 | ||||||
|         let prev_content = if let Some(raw) = prev_content { |         let prev_content = if let Some(raw) = prev_content { | ||||||
|             Some(C::from_parts(&event_type, &raw).map_err(A::Error::custom)?) |             Some(C::from_parts(&event_type, raw).map_err(A::Error::custom)?) | ||||||
|         } else { |         } else { | ||||||
|             None |             None | ||||||
|         }; |         }; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user