Add incoming_derive to Outgoing derive macro

This commit is contained in:
Jonas Platte 2020-08-17 21:46:12 +02:00
parent 4a52931af7
commit f101611c3d
No known key found for this signature in database
GPG Key ID: CC154DE0E30B7C67
2 changed files with 30 additions and 10 deletions

View File

@ -2,8 +2,9 @@ use proc_macro2::{Span, TokenStream};
use quote::{format_ident, quote}; use quote::{format_ident, quote};
use syn::{ use syn::{
parse_quote, AngleBracketedGenericArguments, Attribute, Data, DeriveInput, Field, Fields, parse_quote, AngleBracketedGenericArguments, Attribute, Data, DeriveInput, Field, Fields,
GenericArgument, GenericParam, Generics, ImplGenerics, ParenthesizedGenericArguments, GenericArgument, GenericParam, Generics, ImplGenerics, Meta, MetaList,
PathArguments, Type, TypeGenerics, TypePath, TypeReference, TypeSlice, Variant, ParenthesizedGenericArguments, PathArguments, Type, TypeGenerics, TypePath, TypeReference,
TypeSlice, Variant,
}; };
use crate::util::import_ruma_api; use crate::util::import_ruma_api;
@ -22,11 +23,30 @@ enum DataKind {
pub fn expand_derive_outgoing(input: DeriveInput) -> syn::Result<TokenStream> { pub fn expand_derive_outgoing(input: DeriveInput) -> syn::Result<TokenStream> {
let import_path = import_ruma_api(); let import_path = import_ruma_api();
let derive_deserialize = if no_deserialize_in_attrs(&input.attrs) { let mut derives = vec![quote! { Debug }];
TokenStream::new() if !no_deserialize_in_attrs(&input.attrs) {
} else { derives.push(quote! { #import_path::exports::serde::Deserialize });
quote! { #import_path::exports::serde::Deserialize } }
}; derives.extend(
input
.attrs
.iter()
.filter(|attr| attr.path.is_ident("incoming_derive"))
.map(|attr| {
let meta = attr.parse_meta()?;
match meta {
Meta::List(MetaList { nested, .. }) => Ok(nested),
_ => Err(syn::Error::new_spanned(
meta,
"incoming_derive should be used as `#[incoming_derive(A, B, C)]`",
)),
}
})
.collect::<syn::Result<Vec<_>>>()?
.into_iter()
.flatten()
.map(|derive_mac| quote! { #derive_mac }),
);
let input_attrs = let input_attrs =
input.attrs.iter().filter(|attr| filter_input_attrs(attr)).collect::<Vec<_>>(); input.attrs.iter().filter(|attr| filter_input_attrs(attr)).collect::<Vec<_>>();
@ -73,7 +93,7 @@ pub fn expand_derive_outgoing(input: DeriveInput) -> syn::Result<TokenStream> {
Ok(quote! { Ok(quote! {
#[doc = #doc] #[doc = #doc]
#[derive(Debug, #derive_deserialize)] #[derive( #( #derives ),* )]
#( #input_attrs )* #( #input_attrs )*
#vis enum #incoming_ident #ty_gen { #( #vars, )* } #vis enum #incoming_ident #ty_gen { #( #vars, )* }
@ -111,7 +131,7 @@ pub fn expand_derive_outgoing(input: DeriveInput) -> syn::Result<TokenStream> {
Ok(quote! { Ok(quote! {
#[doc = #doc] #[doc = #doc]
#[derive(Debug, #derive_deserialize)] #[derive( #( #derives ),* )]
#( #input_attrs )* #( #input_attrs )*
#vis struct #incoming_ident #ty_gen #struct_def #vis struct #incoming_ident #ty_gen #struct_def

View File

@ -76,7 +76,7 @@ struct IncomingMyType {
``` ```
*/ */
#[proc_macro_derive(Outgoing, attributes(incoming_no_deserialize))] #[proc_macro_derive(Outgoing, attributes(incoming_derive, incoming_no_deserialize))]
pub fn derive_outgoing(input: TokenStream) -> TokenStream { pub fn derive_outgoing(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput); let input = parse_macro_input!(input as DeriveInput);
expand_derive_outgoing(input).unwrap_or_else(|err| err.to_compile_error()).into() expand_derive_outgoing(input).unwrap_or_else(|err| err.to_compile_error()).into()