Outgoing derive: Replace incoming_no_deserialize with incoming_derive(!Deserialize)
This commit is contained in:
parent
a1ee6c74c0
commit
30a0a39d2b
@ -494,7 +494,7 @@ impl ToTokens for Request {
|
||||
|
||||
let request = quote! {
|
||||
#[derive(Debug, Clone, #import_path::Outgoing)]
|
||||
#[incoming_no_deserialize]
|
||||
#[incoming_derive(!Deserialize)]
|
||||
#( #struct_attributes )*
|
||||
pub struct Request #request_generics #request_def
|
||||
|
||||
|
@ -283,7 +283,7 @@ impl ToTokens for Response {
|
||||
|
||||
let response = quote! {
|
||||
#[derive(Debug, Clone, #import_path::Outgoing)]
|
||||
#[incoming_no_deserialize]
|
||||
#[incoming_derive(!Deserialize)]
|
||||
#( #struct_attributes )*
|
||||
pub struct Response #response_def
|
||||
|
||||
|
@ -1,10 +1,12 @@
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
use quote::{format_ident, quote};
|
||||
use syn::{
|
||||
parse_quote, AngleBracketedGenericArguments, Attribute, Data, DeriveInput, Field, Fields,
|
||||
GenericArgument, GenericParam, Generics, ImplGenerics, Meta, MetaList,
|
||||
ParenthesizedGenericArguments, PathArguments, Type, TypeGenerics, TypePath, TypeReference,
|
||||
TypeSlice, Variant,
|
||||
parse::{Parse, ParseStream},
|
||||
parse_quote,
|
||||
punctuated::Punctuated,
|
||||
AngleBracketedGenericArguments, Attribute, Data, DeriveInput, Field, Fields, GenericArgument,
|
||||
GenericParam, Generics, Ident, ImplGenerics, ParenthesizedGenericArguments, PathArguments,
|
||||
Token, Type, TypeGenerics, TypePath, TypeReference, TypeSlice, Variant,
|
||||
};
|
||||
|
||||
use crate::util::import_ruma_api;
|
||||
@ -24,29 +26,28 @@ pub fn expand_derive_outgoing(input: DeriveInput) -> syn::Result<TokenStream> {
|
||||
let import_path = import_ruma_api();
|
||||
|
||||
let mut derives = vec![quote! { Debug }];
|
||||
if !no_deserialize_in_attrs(&input.attrs) {
|
||||
derives.push(quote! { #import_path::exports::serde::Deserialize });
|
||||
}
|
||||
let mut derive_deserialize = true;
|
||||
|
||||
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<_>>>()?
|
||||
.map(|attr| attr.parse_args())
|
||||
.collect::<syn::Result<Vec<Meta>>>()?
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.map(|derive_mac| quote! { #derive_mac }),
|
||||
.flat_map(|meta| meta.derive_macs)
|
||||
.filter_map(|derive_mac| match derive_mac {
|
||||
DeriveMac::Regular(id) => Some(quote! { #id }),
|
||||
DeriveMac::NegativeDeserialize => {
|
||||
derive_deserialize = false;
|
||||
None
|
||||
}
|
||||
}),
|
||||
);
|
||||
if derive_deserialize {
|
||||
derives.push(quote! { #import_path::exports::serde::Deserialize });
|
||||
}
|
||||
|
||||
let input_attrs =
|
||||
input.attrs.iter().filter(|attr| filter_input_attrs(attr)).collect::<Vec<_>>();
|
||||
@ -149,10 +150,6 @@ fn filter_input_attrs(attr: &Attribute) -> bool {
|
||||
attr.path.is_ident("serde") || attr.path.is_ident("non_exhaustive")
|
||||
}
|
||||
|
||||
fn no_deserialize_in_attrs(attrs: &[Attribute]) -> bool {
|
||||
attrs.iter().any(|attr| attr.path.is_ident("incoming_no_deserialize"))
|
||||
}
|
||||
|
||||
fn impl_outgoing_with_incoming_self(input: &DeriveInput, import_path: &TokenStream) -> TokenStream {
|
||||
let ident = &input.ident;
|
||||
let (impl_gen, ty_gen, _) = input.generics.split_for_impl();
|
||||
@ -283,3 +280,41 @@ fn strip_lifetimes(field_type: &mut Type) -> bool {
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Meta {
|
||||
derive_macs: Vec<DeriveMac>,
|
||||
}
|
||||
|
||||
impl Parse for Meta {
|
||||
fn parse(input: ParseStream) -> syn::Result<Self> {
|
||||
Ok(Self {
|
||||
derive_macs: Punctuated::<_, Token![,]>::parse_terminated(input)?.into_iter().collect(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub enum DeriveMac {
|
||||
Regular(Ident),
|
||||
NegativeDeserialize,
|
||||
}
|
||||
|
||||
impl Parse for DeriveMac {
|
||||
fn parse(input: ParseStream) -> syn::Result<Self> {
|
||||
if input.peek(Token![!]) {
|
||||
let _: Token![!] = input.parse()?;
|
||||
let mac: Ident = input.parse()?;
|
||||
|
||||
if mac != "Deserialize" {
|
||||
return Err(syn::Error::new_spanned(
|
||||
mac,
|
||||
"Negative incoming_derive can only be used for Deserialize",
|
||||
));
|
||||
}
|
||||
|
||||
Ok(Self::NegativeDeserialize)
|
||||
} else {
|
||||
let mac = input.parse()?;
|
||||
Ok(Self::Regular(mac))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ struct IncomingMyType {
|
||||
```
|
||||
|
||||
*/
|
||||
#[proc_macro_derive(Outgoing, attributes(incoming_derive, incoming_no_deserialize))]
|
||||
#[proc_macro_derive(Outgoing, attributes(incoming_derive))]
|
||||
pub fn derive_outgoing(input: TokenStream) -> TokenStream {
|
||||
let input = parse_macro_input!(input as DeriveInput);
|
||||
expand_derive_outgoing(input).unwrap_or_else(|err| err.to_compile_error()).into()
|
||||
|
@ -21,7 +21,7 @@ pub struct OtherThing<'t> {
|
||||
}
|
||||
|
||||
#[derive(Outgoing)]
|
||||
#[incoming_no_deserialize]
|
||||
#[incoming_derive(!Deserialize)]
|
||||
pub struct FakeRequest<'a, T> {
|
||||
pub abc: &'a str,
|
||||
pub thing: Thing<'a, T>,
|
||||
@ -35,7 +35,7 @@ pub struct FakeRequest<'a, T> {
|
||||
}
|
||||
|
||||
#[derive(Outgoing)]
|
||||
#[incoming_no_deserialize]
|
||||
#[incoming_derive(!Deserialize)]
|
||||
pub enum EnumThing<'a, T> {
|
||||
Abc(&'a str),
|
||||
Stuff(Thing<'a, T>),
|
||||
|
@ -19,7 +19,7 @@ use serde_json::value::RawValue as RawJsonValue;
|
||||
/// Send a message event to a room.
|
||||
#[derive(Clone, Debug, Outgoing)]
|
||||
#[non_exhaustive]
|
||||
#[incoming_no_deserialize]
|
||||
#[incoming_derive(!Deserialize)]
|
||||
pub struct Request<'a> {
|
||||
/// The room to send the event to.
|
||||
pub room_id: &'a RoomId,
|
||||
@ -45,7 +45,7 @@ impl<'a> Request<'a> {
|
||||
/// Data in the response from the `send_message_event` API endpoint.
|
||||
#[derive(Clone, Debug, Outgoing)]
|
||||
#[non_exhaustive]
|
||||
#[incoming_no_deserialize]
|
||||
#[incoming_derive(!Deserialize)]
|
||||
pub struct Response {
|
||||
/// A unique identifier for the event.
|
||||
pub event_id: EventId,
|
||||
|
@ -19,7 +19,7 @@ use serde_json::value::RawValue as RawJsonValue;
|
||||
/// Send a state event to a room associated with the empty state key.
|
||||
#[derive(Clone, Debug, Outgoing)]
|
||||
#[non_exhaustive]
|
||||
#[incoming_no_deserialize]
|
||||
#[incoming_derive(!Deserialize)]
|
||||
pub struct Request<'a> {
|
||||
/// The room to set the state in.
|
||||
pub room_id: &'a RoomId,
|
||||
@ -38,7 +38,7 @@ impl<'a> Request<'a> {
|
||||
/// Data in the response from the `send_state_event_for_empty_key` API endpoint.
|
||||
#[derive(Clone, Debug, Outgoing)]
|
||||
#[non_exhaustive]
|
||||
#[incoming_no_deserialize]
|
||||
#[incoming_derive(!Deserialize)]
|
||||
pub struct Response {
|
||||
/// A unique identifier for the event.
|
||||
pub event_id: EventId,
|
||||
|
@ -19,7 +19,7 @@ use serde_json::value::RawValue as RawJsonValue;
|
||||
/// Send a state event to a room associated with a given state key.
|
||||
#[derive(Clone, Debug, Outgoing)]
|
||||
#[non_exhaustive]
|
||||
#[incoming_no_deserialize]
|
||||
#[incoming_derive(!Deserialize)]
|
||||
pub struct Request<'a> {
|
||||
/// The room to set the state in.
|
||||
pub room_id: &'a RoomId,
|
||||
@ -41,7 +41,7 @@ impl<'a> Request<'a> {
|
||||
/// Data in the response from the `send_message_event` API endpoint.
|
||||
#[derive(Clone, Debug, Outgoing)]
|
||||
#[non_exhaustive]
|
||||
#[incoming_no_deserialize]
|
||||
#[incoming_derive(!Deserialize)]
|
||||
pub struct Response {
|
||||
/// A unique identifier for the event.
|
||||
pub event_id: EventId,
|
||||
|
Loading…
x
Reference in New Issue
Block a user