11use proc_macro2:: { Span , TokenStream } ;
22use quote:: quote;
33use std:: iter;
4- use syn:: { Data , DataStruct , DeriveInput , Error , Fields , Ident } ;
4+ use syn:: visit_mut:: VisitMut ;
5+ use syn:: { Data , DataStruct , DeriveInput , Error , Fields , Ident , Lifetime } ;
56
67use crate :: accepts;
7- use crate :: composites:: Field ;
8+ use crate :: composites:: { Field , RenameLifetimes , DEFAULT_LIFETIME } ;
89use crate :: enums:: Variant ;
910use crate :: overrides:: Overrides ;
1011
@@ -58,10 +59,25 @@ pub fn expand_derive_fromsql(input: DeriveInput) -> Result<TokenStream, Error> {
5859 } ;
5960
6061 let ident = & input. ident ;
62+ let mut generics = input. generics ;
63+ if generics. type_params ( ) . count ( ) > 0 {
64+ return Err ( Error :: new_spanned (
65+ & generics,
66+ "#[derive(FromSql)] does not support type parameters." ,
67+ ) ) ;
68+ }
69+ let type_generics = if generics. lifetimes ( ) . count ( ) > 0 {
70+ RenameLifetimes . visit_generics_mut ( & mut generics) ;
71+ let ( _impl, typ, _where) = generics. split_for_impl ( ) ;
72+ Some ( typ)
73+ } else {
74+ None
75+ } ;
76+ let lifetime = Lifetime :: new ( & format ! ( "'{}" , DEFAULT_LIFETIME ) , Span :: call_site ( ) ) ;
6177 let out = quote ! {
62- impl < ' a > postgres_types:: FromSql <' a > for #ident {
63- fn from_sql( _type: & postgres_types:: Type , buf: & ' a [ u8 ] )
64- -> std:: result:: Result <#ident,
78+ impl <#lifetime > postgres_types:: FromSql <#lifetime > for #ident #type_generics {
79+ fn from_sql( _type: & postgres_types:: Type , buf: & #lifetime [ u8 ] )
80+ -> std:: result:: Result <#ident #type_generics ,
6581 std:: boxed:: Box <dyn std:: error:: Error +
6682 std:: marker:: Sync +
6783 std:: marker:: Send >> {
@@ -97,9 +113,9 @@ fn enum_body(ident: &Ident, variants: &[Variant]) -> TokenStream {
97113
98114// Domains are sometimes but not always just represented by the bare type (!?)
99115fn domain_accepts_body ( name : & str , field : & syn:: Field ) -> TokenStream {
100- let ty = & field. ty ;
101- let normal_body = accepts :: domain_body ( name , field ) ;
102-
116+ let mut ty = field. ty . clone ( ) ;
117+ RenameLifetimes . visit_type_mut ( & mut ty ) ;
118+ let normal_body = accepts :: domain_body ( name , "FromSql" , field ) ;
103119 quote ! {
104120 if <#ty as postgres_types:: FromSql >:: accepts( type_) {
105121 return true ;
@@ -110,7 +126,8 @@ fn domain_accepts_body(name: &str, field: &syn::Field) -> TokenStream {
110126}
111127
112128fn domain_body ( ident : & Ident , field : & syn:: Field ) -> TokenStream {
113- let ty = & field. ty ;
129+ let mut ty = field. ty . clone ( ) ;
130+ RenameLifetimes . visit_type_mut ( & mut ty) ;
114131 quote ! {
115132 <#ty as postgres_types:: FromSql >:: from_sql( _type, buf) . map( #ident)
116133 }
0 commit comments