Jonas Platte 0c6dd0ba32
Simplify proc_macro tests
… by moving them from ruma-events-macros to ruma-events and updating the
macros to work in different contexts (without items like FromRaw being
available at the calling crate's root)
2020-03-17 13:10:40 +01:00

49 lines
1.5 KiB
Rust

//! Implementation of the `FromRaw` derive macro
use proc_macro2::TokenStream;
use quote::{quote, quote_spanned};
use syn::{spanned::Spanned, Data, DeriveInput, Fields};
/// Create a `FromRaw` implementation for a struct
pub fn expand_from_raw(input: DeriveInput) -> syn::Result<TokenStream> {
let fields = match input.data {
Data::Struct(s) => match s.fields {
Fields::Named(fs) => fs.named,
_ => panic!("#[derive(FromRaw)] only supports structs with named fields!"),
},
_ => panic!("#[derive(FromRaw)] only supports structs!"),
};
let ident = &input.ident;
let init_list = fields.iter().map(|field| {
let field_ident = field.ident.as_ref().unwrap();
let field_span = field.span();
if field_ident == "content" {
quote_spanned! {field_span=>
content: ::ruma_events::FromRaw::from_raw(raw.content),
}
} else if field_ident == "prev_content" {
quote_spanned! {field_span=>
prev_content: raw.prev_content.map(::ruma_events::FromRaw::from_raw),
}
} else {
quote_spanned! {field_span=>
#field_ident: raw.#field_ident,
}
}
});
Ok(quote! {
impl ::ruma_events::FromRaw for #ident {
type Raw = raw::#ident;
fn from_raw(raw: raw::#ident) -> Self {
Self {
#(#init_list)*
}
}
}
})
}