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 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<TokenStream> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) mod raw {
|
||||
use super::*;
|
||||
|
||||
#raw_content
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -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<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 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
10
src/lib.rs
10
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<Self, InvalidEvent>;
|
||||
fn from_parts(event_type: &str, content: Box<RawJsonValue>) -> Result<Self, InvalidEvent>;
|
||||
|
||||
/// A matrix event identifier, like `m.room.message`.
|
||||
fn event_type(&self) -> &str;
|
||||
|
@ -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<Self, InvalidEvent> {
|
||||
fn from_parts(event_type: &str, content: Box<RawJsonValue>) -> Result<Self, InvalidEvent> {
|
||||
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::<AliasesEventContent>(content.get()).map_err(|e| InvalidEvent {
|
||||
kind: InvalidEventKind::Deserialization,
|
||||
message: e.to_string(),
|
||||
})
|
||||
|
||||
let ev_json = EventJson::from(content);
|
||||
ev_json.deserialize()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<Self, InvalidEvent> {
|
||||
fn from_parts(event_type: &str, content: Box<RawJsonValue>) -> Result<Self, InvalidEvent> {
|
||||
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::<AvatarEventContent>(content.get()).map_err(|e| InvalidEvent {
|
||||
kind: InvalidEventKind::Deserialization,
|
||||
message: e.to_string(),
|
||||
})
|
||||
|
||||
let ev_json = EventJson::from(content);
|
||||
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>(
|
||||
ev_type: &str,
|
||||
input: &RawJsonValue,
|
||||
input: Box<RawJsonValue>,
|
||||
variant: fn(T) -> AnyStateEventContent,
|
||||
) -> Result<AnyStateEventContent, InvalidEvent> {
|
||||
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 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<C> {
|
||||
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
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user