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! {
|
let request = quote! {
|
||||||
#[derive(Debug, Clone, #import_path::Outgoing)]
|
#[derive(Debug, Clone, #import_path::Outgoing)]
|
||||||
#[incoming_no_deserialize]
|
#[incoming_derive(!Deserialize)]
|
||||||
#( #struct_attributes )*
|
#( #struct_attributes )*
|
||||||
pub struct Request #request_generics #request_def
|
pub struct Request #request_generics #request_def
|
||||||
|
|
||||||
|
@ -283,7 +283,7 @@ impl ToTokens for Response {
|
|||||||
|
|
||||||
let response = quote! {
|
let response = quote! {
|
||||||
#[derive(Debug, Clone, #import_path::Outgoing)]
|
#[derive(Debug, Clone, #import_path::Outgoing)]
|
||||||
#[incoming_no_deserialize]
|
#[incoming_derive(!Deserialize)]
|
||||||
#( #struct_attributes )*
|
#( #struct_attributes )*
|
||||||
pub struct Response #response_def
|
pub struct Response #response_def
|
||||||
|
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
use proc_macro2::{Span, TokenStream};
|
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::{Parse, ParseStream},
|
||||||
GenericArgument, GenericParam, Generics, ImplGenerics, Meta, MetaList,
|
parse_quote,
|
||||||
ParenthesizedGenericArguments, PathArguments, Type, TypeGenerics, TypePath, TypeReference,
|
punctuated::Punctuated,
|
||||||
TypeSlice, Variant,
|
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;
|
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 import_path = import_ruma_api();
|
||||||
|
|
||||||
let mut derives = vec![quote! { Debug }];
|
let mut derives = vec![quote! { Debug }];
|
||||||
if !no_deserialize_in_attrs(&input.attrs) {
|
let mut derive_deserialize = true;
|
||||||
derives.push(quote! { #import_path::exports::serde::Deserialize });
|
|
||||||
}
|
|
||||||
derives.extend(
|
derives.extend(
|
||||||
input
|
input
|
||||||
.attrs
|
.attrs
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|attr| attr.path.is_ident("incoming_derive"))
|
.filter(|attr| attr.path.is_ident("incoming_derive"))
|
||||||
.map(|attr| {
|
.map(|attr| attr.parse_args())
|
||||||
let meta = attr.parse_meta()?;
|
.collect::<syn::Result<Vec<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()
|
.into_iter()
|
||||||
.flatten()
|
.flat_map(|meta| meta.derive_macs)
|
||||||
.map(|derive_mac| quote! { #derive_mac }),
|
.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 =
|
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<_>>();
|
||||||
@ -149,10 +150,6 @@ fn filter_input_attrs(attr: &Attribute) -> bool {
|
|||||||
attr.path.is_ident("serde") || attr.path.is_ident("non_exhaustive")
|
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 {
|
fn impl_outgoing_with_incoming_self(input: &DeriveInput, import_path: &TokenStream) -> TokenStream {
|
||||||
let ident = &input.ident;
|
let ident = &input.ident;
|
||||||
let (impl_gen, ty_gen, _) = input.generics.split_for_impl();
|
let (impl_gen, ty_gen, _) = input.generics.split_for_impl();
|
||||||
@ -283,3 +280,41 @@ fn strip_lifetimes(field_type: &mut Type) -> bool {
|
|||||||
_ => false,
|
_ => 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 {
|
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()
|
||||||
|
@ -21,7 +21,7 @@ pub struct OtherThing<'t> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Outgoing)]
|
#[derive(Outgoing)]
|
||||||
#[incoming_no_deserialize]
|
#[incoming_derive(!Deserialize)]
|
||||||
pub struct FakeRequest<'a, T> {
|
pub struct FakeRequest<'a, T> {
|
||||||
pub abc: &'a str,
|
pub abc: &'a str,
|
||||||
pub thing: Thing<'a, T>,
|
pub thing: Thing<'a, T>,
|
||||||
@ -35,7 +35,7 @@ pub struct FakeRequest<'a, T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Outgoing)]
|
#[derive(Outgoing)]
|
||||||
#[incoming_no_deserialize]
|
#[incoming_derive(!Deserialize)]
|
||||||
pub enum EnumThing<'a, T> {
|
pub enum EnumThing<'a, T> {
|
||||||
Abc(&'a str),
|
Abc(&'a str),
|
||||||
Stuff(Thing<'a, T>),
|
Stuff(Thing<'a, T>),
|
||||||
|
@ -19,7 +19,7 @@ use serde_json::value::RawValue as RawJsonValue;
|
|||||||
/// Send a message event to a room.
|
/// Send a message event to a room.
|
||||||
#[derive(Clone, Debug, Outgoing)]
|
#[derive(Clone, Debug, Outgoing)]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
#[incoming_no_deserialize]
|
#[incoming_derive(!Deserialize)]
|
||||||
pub struct Request<'a> {
|
pub struct Request<'a> {
|
||||||
/// The room to send the event to.
|
/// The room to send the event to.
|
||||||
pub room_id: &'a RoomId,
|
pub room_id: &'a RoomId,
|
||||||
@ -45,7 +45,7 @@ impl<'a> Request<'a> {
|
|||||||
/// Data in the response from the `send_message_event` API endpoint.
|
/// Data in the response from the `send_message_event` API endpoint.
|
||||||
#[derive(Clone, Debug, Outgoing)]
|
#[derive(Clone, Debug, Outgoing)]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
#[incoming_no_deserialize]
|
#[incoming_derive(!Deserialize)]
|
||||||
pub struct Response {
|
pub struct Response {
|
||||||
/// A unique identifier for the event.
|
/// A unique identifier for the event.
|
||||||
pub event_id: EventId,
|
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.
|
/// Send a state event to a room associated with the empty state key.
|
||||||
#[derive(Clone, Debug, Outgoing)]
|
#[derive(Clone, Debug, Outgoing)]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
#[incoming_no_deserialize]
|
#[incoming_derive(!Deserialize)]
|
||||||
pub struct Request<'a> {
|
pub struct Request<'a> {
|
||||||
/// The room to set the state in.
|
/// The room to set the state in.
|
||||||
pub room_id: &'a RoomId,
|
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.
|
/// Data in the response from the `send_state_event_for_empty_key` API endpoint.
|
||||||
#[derive(Clone, Debug, Outgoing)]
|
#[derive(Clone, Debug, Outgoing)]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
#[incoming_no_deserialize]
|
#[incoming_derive(!Deserialize)]
|
||||||
pub struct Response {
|
pub struct Response {
|
||||||
/// A unique identifier for the event.
|
/// A unique identifier for the event.
|
||||||
pub event_id: EventId,
|
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.
|
/// Send a state event to a room associated with a given state key.
|
||||||
#[derive(Clone, Debug, Outgoing)]
|
#[derive(Clone, Debug, Outgoing)]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
#[incoming_no_deserialize]
|
#[incoming_derive(!Deserialize)]
|
||||||
pub struct Request<'a> {
|
pub struct Request<'a> {
|
||||||
/// The room to set the state in.
|
/// The room to set the state in.
|
||||||
pub room_id: &'a RoomId,
|
pub room_id: &'a RoomId,
|
||||||
@ -41,7 +41,7 @@ impl<'a> Request<'a> {
|
|||||||
/// Data in the response from the `send_message_event` API endpoint.
|
/// Data in the response from the `send_message_event` API endpoint.
|
||||||
#[derive(Clone, Debug, Outgoing)]
|
#[derive(Clone, Debug, Outgoing)]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
#[incoming_no_deserialize]
|
#[incoming_derive(!Deserialize)]
|
||||||
pub struct Response {
|
pub struct Response {
|
||||||
/// A unique identifier for the event.
|
/// A unique identifier for the event.
|
||||||
pub event_id: EventId,
|
pub event_id: EventId,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user