From ae6595339cdd5316887b11bf69bdf8dabc1a0f74 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Sun, 13 Dec 2020 11:54:33 +0100 Subject: [PATCH] Stop stripping serde attributes To still prevent 'unknown attribute' errors, the attribute is registered using a dummy derive macro where needed. --- ruma-api-macros/src/api.rs | 9 +-------- ruma-api-macros/src/api/request.rs | 10 +++------- ruma-api-macros/src/api/response.rs | 11 +++-------- ruma-serde-macros/src/lib.rs | 9 +++++++++ ruma-serde-macros/src/outgoing.rs | 9 ++++++--- 5 files changed, 22 insertions(+), 26 deletions(-) diff --git a/ruma-api-macros/src/api.rs b/ruma-api-macros/src/api.rs index b8a1a994..dfe227ec 100644 --- a/ruma-api-macros/src/api.rs +++ b/ruma-api-macros/src/api.rs @@ -4,7 +4,7 @@ use proc_macro2::TokenStream; use quote::{quote, ToTokens}; use syn::{ parse::{Parse, ParseStream}, - Field, Token, Type, + Token, Type, }; pub(crate) mod attribute; @@ -15,13 +15,6 @@ pub(crate) mod response; use self::{metadata::Metadata, request::Request, response::Response}; use crate::util; -/// Removes `serde` attributes from struct fields. -pub fn strip_serde_attrs(field: &Field) -> Field { - let mut field = field.clone(); - field.attrs.retain(|attr| !attr.path.is_ident("serde")); - field -} - /// The result of processing the `ruma_api` macro, ready for output back to source code. pub struct Api { /// The `metadata` section of the macro. diff --git a/ruma-api-macros/src/api/request.rs b/ruma-api-macros/src/api/request.rs index 705b74a4..a52d92de 100644 --- a/ruma-api-macros/src/api/request.rs +++ b/ruma-api-macros/src/api/request.rs @@ -12,10 +12,7 @@ use syn::{ }; use crate::{ - api::{ - attribute::{Meta, MetaNameValue}, - strip_serde_attrs, - }, + api::attribute::{Meta, MetaNameValue}, util, }; @@ -450,8 +447,7 @@ impl ToTokens for Request { let request_def = if self.fields.is_empty() { quote!(;) } else { - let fields = - self.fields.iter().map(|request_field| strip_serde_attrs(request_field.field())); + let fields = self.fields.iter().map(|request_field| request_field.field()); quote! { { #(#fields),* } } }; @@ -540,7 +536,7 @@ impl ToTokens for Request { }; let request = quote! { - #[derive(Debug, Clone, #ruma_serde::Outgoing)] + #[derive(Debug, Clone, #ruma_serde::Outgoing, #ruma_serde::_FakeDeriveSerde)] #[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] #[incoming_derive(!Deserialize)] #( #struct_attributes )* diff --git a/ruma-api-macros/src/api/response.rs b/ruma-api-macros/src/api/response.rs index 976efa19..8738013b 100644 --- a/ruma-api-macros/src/api/response.rs +++ b/ruma-api-macros/src/api/response.rs @@ -12,10 +12,7 @@ use syn::{ }; use crate::{ - api::{ - attribute::{Meta, MetaNameValue}, - strip_serde_attrs, - }, + api::attribute::{Meta, MetaNameValue}, util, }; @@ -320,9 +317,7 @@ impl ToTokens for Response { let response_def = if self.fields.is_empty() { quote!(;) } else { - let fields = - self.fields.iter().map(|response_field| strip_serde_attrs(response_field.field())); - + let fields = self.fields.iter().map(|response_field| response_field.field()); quote! { { #(#fields),* } } }; @@ -347,7 +342,7 @@ impl ToTokens for Response { }; let response = quote! { - #[derive(Debug, Clone, #ruma_serde::Outgoing)] + #[derive(Debug, Clone, #ruma_serde::Outgoing, #ruma_serde::_FakeDeriveSerde)] #[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] #[incoming_derive(!Deserialize)] #( #struct_attributes )* diff --git a/ruma-serde-macros/src/lib.rs b/ruma-serde-macros/src/lib.rs index 7c6cdde8..c1bd0d2a 100644 --- a/ruma-serde-macros/src/lib.rs +++ b/ruma-serde-macros/src/lib.rs @@ -125,3 +125,12 @@ pub fn derive_string_enum(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as ItemEnum); expand_all(input).unwrap_or_else(|err| err.to_compile_error()).into() } + +/// A derive macro that generates no code, but registers the serde attribute so both `#[serde(...)]` +/// and `#[cfg_attr(..., serde(...))]` are accepted on the type, its fields and (in case the input +/// is an enum) variants fields. +#[doc(hidden)] +#[proc_macro_derive(_FakeDeriveSerde, attributes(serde))] +pub fn fake_derive_serde(_input: TokenStream) -> TokenStream { + TokenStream::new() +} diff --git a/ruma-serde-macros/src/outgoing.rs b/ruma-serde-macros/src/outgoing.rs index aaf637ee..55aad378 100644 --- a/ruma-serde-macros/src/outgoing.rs +++ b/ruma-serde-macros/src/outgoing.rs @@ -45,9 +45,12 @@ pub fn expand_derive_outgoing(input: DeriveInput) -> syn::Result { } }), ); - if derive_deserialize { - derives.push(quote! { #ruma_serde::exports::serde::Deserialize }); - } + + derives.push(if derive_deserialize { + quote! { #ruma_serde::exports::serde::Deserialize } + } else { + quote! { #ruma_serde::_FakeDeriveSerde } + }); let input_attrs = input.attrs.iter().filter(|attr| filter_input_attrs(attr)).collect::>();