From a0186f4a6373c00ca5e9f20eb0927640f54ca23b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= Date: Fri, 24 Nov 2023 15:51:59 +0100 Subject: [PATCH] Keep full generics data --- src/lib.rs | 15 +++++++++------ src/parse.rs | 12 +++--------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 92ab0a6..dc70d15 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -32,7 +32,7 @@ mod parse; use proc_macro::TokenStream; use quote::{format_ident, quote}; -use syn::parse_macro_input; +use syn::{parse_macro_input, Lifetime, LifetimeParam}; use crate::parse::Input; @@ -85,10 +85,11 @@ pub fn derive_serialize(input: TokenStream) -> TokenStream { let ident = input.ident; let num_fields = count_serialized_fields(&input.fields); let serialize_fields = serialize_fields(&input.fields, input.attrs.offset); - let lifetimes = &input.lifetimes; + let lifetimes_imp = input.generics.lifetimes(); + let lifetimes_ty = input.generics.lifetimes(); TokenStream::from(quote! { - impl<#(#lifetimes),*> serde::Serialize for #ident<#(#lifetimes),*> { + impl<#(#lifetimes_imp),*> serde::Serialize for #ident<#(#lifetimes_ty),*> { fn serialize(&self, serializer: S) -> core::result::Result where S: serde::Serializer @@ -168,7 +169,8 @@ fn all_fields(fields: &[parse::Field]) -> Vec { .collect() } -fn de_lifetime(lifetimes: &[syn::Lifetime]) -> proc_macro2::TokenStream { +fn de_lifetime<'a>(lifetimes: impl Iterator) -> proc_macro2::TokenStream { + let lifetimes = lifetimes.map(|l| &l.lifetime); quote! { 'de: #(#lifetimes)+* } @@ -182,8 +184,9 @@ pub fn derive_deserialize(input: TokenStream) -> TokenStream { let unwrap_expected_fields = unwrap_expected_fields(&input.fields); let match_fields = match_fields(&input.fields, input.attrs.offset); let all_fields = all_fields(&input.fields); - let de_lifetime = de_lifetime(&input.lifetimes); - let lifetimes = input.lifetimes; + let de_lifetime = de_lifetime(input.generics.lifetimes()); + let lifetimes: Vec<_> = input.generics.lifetimes().collect(); + let lifetimes = &*lifetimes; let the_loop = if !input.fields.is_empty() { // NB: In the previous "none_fields", we use the actual struct's diff --git a/src/parse.rs b/src/parse.rs index 5528fce..3255dc4 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -1,13 +1,13 @@ use proc_macro2::Span; use syn::meta::ParseNestedMeta; use syn::parse::{Error, Parse, ParseStream, Result}; -use syn::{Data, DeriveInput, Fields, Ident, Lifetime, LitInt, LitStr, Token}; +use syn::{Data, DeriveInput, Fields, Generics, Ident, LitInt, LitStr, Token}; pub struct Input { pub ident: Ident, pub attrs: StructAttrs, pub fields: Vec, - pub lifetimes: Vec, + pub generics: Generics, } #[derive(Default)] @@ -54,10 +54,6 @@ fn parse_attrs(attrs: &Vec) -> Result { Ok(struct_attrs) } -fn lifetimes(generics: &syn::Generics) -> Vec { - generics.lifetimes().map(|l| l.lifetime.clone()).collect() -} - impl Parse for Input { fn parse(input: ParseStream) -> Result { let call_site = Span::call_site(); @@ -81,15 +77,13 @@ impl Parse for Input { let fields = fields_from_ast(&syn_fields.named)?; - let lifetimes = lifetimes(&derive_input.generics); - //serde::internals::ast calls `fields_from_ast(cx, &fields.named, attrs, container_default)` Ok(Input { ident: derive_input.ident, attrs, fields, - lifetimes, + generics: derive_input.generics, }) } }