Stop stripping serde attributes
To still prevent 'unknown attribute' errors, the attribute is registered using a dummy derive macro where needed.
This commit is contained in:
parent
e8b1e35714
commit
ae6595339c
@ -4,7 +4,7 @@ use proc_macro2::TokenStream;
|
|||||||
use quote::{quote, ToTokens};
|
use quote::{quote, ToTokens};
|
||||||
use syn::{
|
use syn::{
|
||||||
parse::{Parse, ParseStream},
|
parse::{Parse, ParseStream},
|
||||||
Field, Token, Type,
|
Token, Type,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) mod attribute;
|
pub(crate) mod attribute;
|
||||||
@ -15,13 +15,6 @@ pub(crate) mod response;
|
|||||||
use self::{metadata::Metadata, request::Request, response::Response};
|
use self::{metadata::Metadata, request::Request, response::Response};
|
||||||
use crate::util;
|
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.
|
/// The result of processing the `ruma_api` macro, ready for output back to source code.
|
||||||
pub struct Api {
|
pub struct Api {
|
||||||
/// The `metadata` section of the macro.
|
/// The `metadata` section of the macro.
|
||||||
|
@ -12,10 +12,7 @@ use syn::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
api::{
|
api::attribute::{Meta, MetaNameValue},
|
||||||
attribute::{Meta, MetaNameValue},
|
|
||||||
strip_serde_attrs,
|
|
||||||
},
|
|
||||||
util,
|
util,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -450,8 +447,7 @@ impl ToTokens for Request {
|
|||||||
let request_def = if self.fields.is_empty() {
|
let request_def = if self.fields.is_empty() {
|
||||||
quote!(;)
|
quote!(;)
|
||||||
} else {
|
} else {
|
||||||
let fields =
|
let fields = self.fields.iter().map(|request_field| request_field.field());
|
||||||
self.fields.iter().map(|request_field| strip_serde_attrs(request_field.field()));
|
|
||||||
quote! { { #(#fields),* } }
|
quote! { { #(#fields),* } }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -540,7 +536,7 @@ impl ToTokens for Request {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let request = quote! {
|
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)]
|
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
|
||||||
#[incoming_derive(!Deserialize)]
|
#[incoming_derive(!Deserialize)]
|
||||||
#( #struct_attributes )*
|
#( #struct_attributes )*
|
||||||
|
@ -12,10 +12,7 @@ use syn::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
api::{
|
api::attribute::{Meta, MetaNameValue},
|
||||||
attribute::{Meta, MetaNameValue},
|
|
||||||
strip_serde_attrs,
|
|
||||||
},
|
|
||||||
util,
|
util,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -320,9 +317,7 @@ impl ToTokens for Response {
|
|||||||
let response_def = if self.fields.is_empty() {
|
let response_def = if self.fields.is_empty() {
|
||||||
quote!(;)
|
quote!(;)
|
||||||
} else {
|
} else {
|
||||||
let fields =
|
let fields = self.fields.iter().map(|response_field| response_field.field());
|
||||||
self.fields.iter().map(|response_field| strip_serde_attrs(response_field.field()));
|
|
||||||
|
|
||||||
quote! { { #(#fields),* } }
|
quote! { { #(#fields),* } }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -347,7 +342,7 @@ impl ToTokens for Response {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let response = quote! {
|
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)]
|
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
|
||||||
#[incoming_derive(!Deserialize)]
|
#[incoming_derive(!Deserialize)]
|
||||||
#( #struct_attributes )*
|
#( #struct_attributes )*
|
||||||
|
@ -125,3 +125,12 @@ pub fn derive_string_enum(input: TokenStream) -> TokenStream {
|
|||||||
let input = parse_macro_input!(input as ItemEnum);
|
let input = parse_macro_input!(input as ItemEnum);
|
||||||
expand_all(input).unwrap_or_else(|err| err.to_compile_error()).into()
|
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()
|
||||||
|
}
|
||||||
|
@ -45,9 +45,12 @@ pub fn expand_derive_outgoing(input: DeriveInput) -> syn::Result<TokenStream> {
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
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 =
|
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<_>>();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user