Generate content types and raw module.

This commit is contained in:
Jimmy Cuadra 2019-06-19 16:08:43 -07:00
parent a5834ea192
commit 3b65905784
4 changed files with 65 additions and 9 deletions

View File

@ -23,5 +23,5 @@ proc-macro = true
[dev-dependencies]
ruma-identifiers = "0.13.1"
serde_json = "1.0.39"
js_int = "0.1.0"
serde = "1.0.92"
js_int = { version = "0.1.0", features = ["serde"] }
serde = { version = "1.0.92", features = ["derive"] }

View File

@ -9,13 +9,16 @@ use syn::{
Attribute, Field, Ident, Token,
};
use crate::parse::{EventKind, RumaEventInput};
use crate::parse::{Content, EventKind, RumaEventInput};
/// The result of processing the `ruma_event` macro, ready for output back to source code.
pub struct RumaEvent {
/// Outer attributes on the field, such as a docstring.
attrs: Vec<Attribute>,
/// Information for generating the type used for the event's `content` field.
content: Content,
/// The name of the type of the event's `content` field.
content_name: Ident,
@ -53,6 +56,7 @@ impl From<RumaEventInput> for RumaEvent {
Self {
attrs: input.attrs,
content: input.content,
content_name,
fields,
kind,
@ -72,16 +76,60 @@ impl ToTokens for RumaEvent {
let content_docstring = format!("The payload for `{}`.", name);
let content = match &self.content {
Content::Struct(fields) => {
quote! {
#[doc = #content_docstring]
#[derive(Clone, Debug)]
pub struct #content_name {
#(#fields),*
}
}
}
Content::Typedef(typedef) => {
let content_attrs = &typedef.attrs;
let path = &typedef.path;
quote! {
#(#content_attrs)*
pub type #content_name = #path;
}
}
};
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 output = quote!(
#(#attrs),*
#(#attrs)*
#[derive(Clone, Debug)]
pub struct #name {
#(#event_fields),*
}
#[doc = #content_docstring]
#[derive(Clone, Debug)]
pub struct #content_name {
#content
/// "Raw" versions of the event and its content which implement `serde::Deserialize`.
mod raw {
use super::*;
#(#attrs)*
#[derive(Clone, Debug, serde::Deserialize)]
pub struct #name {
#(#event_fields),*
}
#raw_content
}
);

View File

@ -109,7 +109,7 @@ mod parse;
/// ///
/// /// A mapping of `UserId`'s to a collection of `RoomId`'s which are considered
/// /// *direct* for that particular user.
/// HashMap<UserId, Vec<ruma_identifiers::RoomId>>
/// std::collections::HashMap<ruma_identifiers::UserId, Vec<ruma_identifiers::RoomId>>
/// }
/// }
/// }

View File

@ -1,5 +1,5 @@
// See note about wrapping macro expansion in a module from `src/lib.rs`
pub mod tests {
pub mod common_case {
use ruma_events_macros::ruma_event;
ruma_event! {
@ -13,6 +13,10 @@ pub mod tests {
}
}
}
}
pub mod extra_fields {
use ruma_events_macros::ruma_event;
ruma_event! {
/// A redaction of an event.
@ -29,6 +33,10 @@ pub mod tests {
},
}
}
}
pub mod type_alias {
use ruma_events_macros::ruma_event;
ruma_event! {
/// Informs the client about the rooms that are considered direct by a user.