From 16a83468ab1443a695b618cac875cca778e714f6 Mon Sep 17 00:00:00 2001 From: Dominic Date: Tue, 14 Jan 2020 02:55:05 +0100 Subject: [PATCH] restrict OpenapiType generic parameters (fixes #3) --- gotham_restful_derive/src/openapi_type.rs | 29 +++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/gotham_restful_derive/src/openapi_type.rs b/gotham_restful_derive/src/openapi_type.rs index 5926a16..f15889e 100644 --- a/gotham_restful_derive/src/openapi_type.rs +++ b/gotham_restful_derive/src/openapi_type.rs @@ -4,6 +4,8 @@ use quote::quote; use syn::{ Field, Fields, + Generics, + GenericParam, Item, ItemEnum, ItemStruct, @@ -22,6 +24,29 @@ pub fn expand(tokens : TokenStream) -> TokenStream }.into() } +fn expand_where(generics : &Generics) -> TokenStream2 +{ + if generics.params.is_empty() + { + quote!() + } + else + { + let krate = super::krate(); + let idents = generics.params.iter() + .map(|param| match param { + GenericParam::Type(ty) => Some(ty.ident.clone()), + _ => None + }) + .filter(|param| param.is_some()) + .map(|param| param.unwrap()); + + quote! { + where #(#idents : #krate::OpenapiType),* + } + } +} + fn expand_variant(variant : &Variant) -> TokenStream2 { if variant.fields != Fields::Unit @@ -41,11 +66,13 @@ fn expand_enum(input : ItemEnum) -> TokenStream2 let krate = super::krate(); let ident = input.ident; let generics = input.generics; + let where_clause = expand_where(&generics); let variants : Vec = input.variants.iter().map(expand_variant).collect(); quote! { impl #generics #krate::OpenapiType for #ident #generics + #where_clause { fn schema() -> #krate::OpenapiSchema { @@ -118,6 +145,7 @@ pub fn expand_struct(input : ItemStruct) -> TokenStream2 let krate = super::krate(); let ident = input.ident; let generics = input.generics; + let where_clause = expand_where(&generics); let fields : Vec = match input.fields { Fields::Named(fields) => { @@ -129,6 +157,7 @@ pub fn expand_struct(input : ItemStruct) -> TokenStream2 quote!{ impl #generics #krate::OpenapiType for #ident #generics + #where_clause { fn schema() -> #krate::OpenapiSchema {