From f0c94958fa5dcf160fc2d26fe1b766448d3dc51c Mon Sep 17 00:00:00 2001 From: "Ragotzy.devin" Date: Sat, 16 May 2020 02:33:04 -0400 Subject: [PATCH] Move `raw` mod into FromRaw derive --- ruma-events-macros/src/from_raw.rs | 16 ++++++++ ruma-events-macros/src/gen.rs | 66 ++---------------------------- src/lib.rs | 10 ++--- src/room/aliases.rs | 11 +++-- src/room/avatar.rs | 11 +++-- src/state.rs | 8 ++-- 6 files changed, 37 insertions(+), 85 deletions(-) diff --git a/ruma-events-macros/src/from_raw.rs b/ruma-events-macros/src/from_raw.rs index f9f0d943..b1f6e391 100644 --- a/ruma-events-macros/src/from_raw.rs +++ b/ruma-events-macros/src/from_raw.rs @@ -15,6 +15,16 @@ pub fn expand_from_raw(input: DeriveInput) -> syn::Result { }; 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 field_ident = field.ident.as_ref().unwrap(); let field_span = field.span(); @@ -44,5 +54,11 @@ pub fn expand_from_raw(input: DeriveInput) -> syn::Result { } } } + + pub(crate) mod raw { + use super::*; + + #raw_content + } }) } diff --git a/ruma-events-macros/src/gen.rs b/ruma-events-macros/src/gen.rs index 4c788908..26c2a57b 100644 --- a/ruma-events-macros/src/gen.rs +++ b/ruma-events-macros/src/gen.rs @@ -3,12 +3,11 @@ #![allow(dead_code)] use proc_macro2::{Span, TokenStream}; -use quote::{format_ident, quote, quote_spanned, ToTokens}; +use quote::{format_ident, quote, ToTokens}; use syn::{ parse::{self, Parse, ParseStream}, parse_quote, punctuated::Punctuated, - spanned::Spanned, Attribute, Field, Ident, LitStr, Token, }; @@ -87,10 +86,9 @@ impl ToTokens for RumaEvent { let content = match &self.content { Content::Struct(fields) => { - // TODO remove serde::Deserialize when this macro actually generates generic events quote! { #[doc = #content_docstring] - #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)] + #[derive(Clone, Debug, serde::Serialize, ::ruma_events_macros::FromRaw)] pub struct #content_name { #(#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 = - 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 output = quote!( - #content - #impl_event_result_compatible_for_content - - /// "Raw" versions of the event and its content which implement `serde::Deserialize`. - pub(crate) mod raw { - use super::*; - - #raw_content - } - ); - - output.to_tokens(tokens); + content.to_tokens(tokens); } } diff --git a/src/lib.rs b/src/lib.rs index 8f82b46d..a81472db 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -120,10 +120,11 @@ use std::fmt::Debug; use js_int::Int; use serde::{Deserialize, Serialize}; +use serde_json::value::RawValue as RawJsonValue; // 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."] pub use ruma_serde::empty::Empty; @@ -141,7 +142,7 @@ pub mod util; extern crate self as ruma_events; pub mod call; -pub mod custom; +// pub mod custom; /// Enums for heterogeneous collections of events. // pub mod collections { // pub mod all; @@ -217,10 +218,7 @@ impl UnsignedData { /// Implementing this trait allows content types to be serialized as well as deserialized. pub trait EventContent: Sized + Serialize { /// Constructs the given event content. - fn from_parts( - event_type: &str, - content: &serde_json::value::RawValue, - ) -> Result; + fn from_parts(event_type: &str, content: Box) -> Result; /// A matrix event identifier, like `m.room.message`. fn event_type(&self) -> &str; diff --git a/src/room/aliases.rs b/src/room/aliases.rs index 72677307..ab9d7386 100644 --- a/src/room/aliases.rs +++ b/src/room/aliases.rs @@ -6,7 +6,7 @@ use serde_json::value::RawValue as RawJsonValue; use crate::{ error::{InvalidEvent, InvalidEventKind}, - EventContent, RoomEventContent, StateEventContent, + EventContent, EventJson, RoomEventContent, StateEventContent, }; ruma_event! { @@ -26,17 +26,16 @@ impl EventContent for AliasesEventContent { "m.room.aliases" } - fn from_parts(event_type: &str, content: &RawJsonValue) -> Result { + fn from_parts(event_type: &str, content: Box) -> Result { if event_type != "m.room.aliases" { return Err(InvalidEvent { kind: InvalidEventKind::Deserialization, message: format!("expected `m.room.aliases` found {}", event_type), }); } - serde_json::from_str::(content.get()).map_err(|e| InvalidEvent { - kind: InvalidEventKind::Deserialization, - message: e.to_string(), - }) + + let ev_json = EventJson::from(content); + ev_json.deserialize() } } diff --git a/src/room/avatar.rs b/src/room/avatar.rs index 54304a80..dcbe67aa 100644 --- a/src/room/avatar.rs +++ b/src/room/avatar.rs @@ -6,7 +6,7 @@ use serde_json::value::RawValue as RawJsonValue; use super::ImageInfo; use crate::{ error::{InvalidEvent, InvalidEventKind}, - EventContent, RoomEventContent, StateEventContent, + EventContent, EventJson, RoomEventContent, StateEventContent, }; ruma_event! { @@ -33,17 +33,16 @@ impl EventContent for AvatarEventContent { "m.room.avatar" } - fn from_parts(event_type: &str, content: &RawJsonValue) -> Result { + fn from_parts(event_type: &str, content: Box) -> Result { if event_type != "m.room.avatar" { return Err(InvalidEvent { kind: InvalidEventKind::Deserialization, message: format!("expected `m.room.avatar` found {}", event_type), }); } - serde_json::from_str::(content.get()).map_err(|e| InvalidEvent { - kind: InvalidEventKind::Deserialization, - message: e.to_string(), - }) + + let ev_json = EventJson::from(content); + ev_json.deserialize() } } diff --git a/src/state.rs b/src/state.rs index cb44c19d..48ae9011 100644 --- a/src/state.rs +++ b/src/state.rs @@ -115,10 +115,10 @@ impl EventContent for AnyStateEventContent { } } - fn from_parts(event_type: &str, content: &RawJsonValue) -> Result { + fn from_parts(event_type: &str, content: Box) -> Result { fn deserialize_variant( ev_type: &str, - input: &RawJsonValue, + input: Box, variant: fn(T) -> AnyStateEventContent, ) -> Result { let content = T::from_parts(ev_type, input)?; @@ -278,7 +278,7 @@ impl<'de, C: StateEventContent> Visitor<'de> for StateEventVisitor { 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 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 sender = sender.ok_or_else(|| de::Error::missing_field("sender"))?; @@ -291,7 +291,7 @@ impl<'de, C: StateEventContent> Visitor<'de> for StateEventVisitor { let state_key = state_key.ok_or_else(|| de::Error::missing_field("state_key"))?; 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 { None };