Limit when RequestQuery impls Deserialize and impl Outgoing

This commit is contained in:
Devin Ragotzy 2020-08-06 16:16:17 -04:00 committed by Jonas Platte
parent 770a68d49b
commit e783288ef0
2 changed files with 27 additions and 6 deletions

View File

@ -422,29 +422,37 @@ impl ToTokens for Request {
let request_query_struct = if let Some(f) = self.query_map_field() { let request_query_struct = if let Some(f) = self.query_map_field() {
let field = Field { ident: None, colon_token: None, ..f.clone() }; let field = Field { ident: None, colon_token: None, ..f.clone() };
let lifetime = self.query_lifetimes(); let (derive_deserialize, lifetime) = if self.has_query_lifetimes() {
(TokenStream::new(), self.query_lifetimes())
} else {
(quote!(::ruma_api::exports::serde::Deserialize), TokenStream::new())
};
quote! { quote! {
/// Data in the request's query string. /// Data in the request's query string.
#[derive( #[derive(
Debug, Debug,
::ruma_api::Outgoing, ::ruma_api::Outgoing,
::ruma_api::exports::serde::Deserialize,
::ruma_api::exports::serde::Serialize, ::ruma_api::exports::serde::Serialize,
#derive_deserialize
)] )]
struct RequestQuery #lifetime (#field); struct RequestQuery #lifetime (#field);
} }
} else if self.has_query_fields() { } else if self.has_query_fields() {
let fields = self.fields.iter().filter_map(RequestField::as_query_field); let fields = self.fields.iter().filter_map(RequestField::as_query_field);
let lifetime = self.query_lifetimes(); let (derive_deserialize, lifetime) = if self.has_query_lifetimes() {
(TokenStream::new(), self.query_lifetimes())
} else {
(quote!(::ruma_api::exports::serde::Deserialize), TokenStream::new())
};
quote! { quote! {
/// Data in the request's query string. /// Data in the request's query string.
#[derive( #[derive(
Debug, Debug,
::ruma_api::Outgoing, ::ruma_api::Outgoing,
::ruma_api::exports::serde::Deserialize,
::ruma_api::exports::serde::Serialize, ::ruma_api::exports::serde::Serialize,
#derive_deserialize
)] )]
struct RequestQuery #lifetime { struct RequestQuery #lifetime {
#(#fields),* #(#fields),*
@ -460,6 +468,7 @@ impl ToTokens for Request {
pub struct Request #request_generics #request_def pub struct Request #request_generics #request_def
#request_body_struct #request_body_struct
#request_query_struct #request_query_struct
}; };

View File

@ -5,8 +5,8 @@ use quote::quote;
use std::collections::BTreeSet; use std::collections::BTreeSet;
use syn::{ use syn::{
AngleBracketedGenericArguments, GenericArgument, Ident, Lifetime, AngleBracketedGenericArguments, GenericArgument, Ident, Lifetime,
ParenthesizedGenericArguments, PathArguments, Type, TypeGroup, TypeParen, TypePath, ParenthesizedGenericArguments, PathArguments, Type, TypeArray, TypeBareFn, TypeGroup,
TypeReference, TypeTuple, TypeParen, TypePath, TypePtr, TypeReference, TypeSlice, TypeTuple,
}; };
use crate::api::{metadata::Metadata, request::Request}; use crate::api::{metadata::Metadata, request::Request};
@ -51,6 +51,18 @@ pub fn collect_lifetime_ident(lifetimes: &mut BTreeSet<Lifetime>, ty: &Type) {
} }
Type::Paren(TypeParen { elem, .. }) => collect_lifetime_ident(lifetimes, &*elem), Type::Paren(TypeParen { elem, .. }) => collect_lifetime_ident(lifetimes, &*elem),
Type::Group(TypeGroup { elem, .. }) => collect_lifetime_ident(lifetimes, &*elem), Type::Group(TypeGroup { elem, .. }) => collect_lifetime_ident(lifetimes, &*elem),
Type::Ptr(TypePtr { elem, .. }) => collect_lifetime_ident(lifetimes, &*elem),
Type::Slice(TypeSlice { elem, .. }) => collect_lifetime_ident(lifetimes, &*elem),
Type::Array(TypeArray { elem, .. }) => collect_lifetime_ident(lifetimes, &*elem),
Type::BareFn(TypeBareFn {
lifetimes: Some(syn::BoundLifetimes { lifetimes: fn_lifetimes, .. }),
..
}) => {
for lt in fn_lifetimes {
let syn::LifetimeDef { lifetime, .. } = lt;
lifetimes.insert(lifetime.clone());
}
}
_ => {} _ => {}
} }
} }