diff --git a/gotham_restful_derive/Cargo.toml b/gotham_restful_derive/Cargo.toml index 1fb4f53..bd7f368 100644 --- a/gotham_restful_derive/Cargo.toml +++ b/gotham_restful_derive/Cargo.toml @@ -22,7 +22,7 @@ lazy_static = "1.4.0" proc-macro2 = "1.0.10" quote = "1.0.3" regex = "1.3.7" -syn = { version = "1.0.17", features = ["extra-traits", "full"] } +syn = "1.0.18" [features] default = [] diff --git a/gotham_restful_derive/src/from_body.rs b/gotham_restful_derive/src/from_body.rs index a027c55..5aa962a 100644 --- a/gotham_restful_derive/src/from_body.rs +++ b/gotham_restful_derive/src/from_body.rs @@ -4,12 +4,14 @@ use quote::{format_ident, quote}; use std::cmp::min; use syn::{ punctuated::Punctuated, + spanned::Spanned, token::Comma, + Data, + DeriveInput, Error, Field, Fields, Ident, - ItemStruct, Type, parse_macro_input }; @@ -50,11 +52,17 @@ impl ParsedFields fn expand(tokens : TokenStream) -> Result { let krate = super::krate(); - let input = parse_macro_input::parse::(tokens)?; + let input = parse_macro_input::parse::(tokens)?; let ident = input.ident; let generics = input.generics; - let fields = match input.fields { + let strukt = match input.data { + Data::Enum(inum) => Err(inum.enum_token.span()), + Data::Struct(strukt) => Ok(strukt), + Data::Union(uni) => Err(uni.union_token.span()) + }.map_err(|span| Error::new(span, "#[derive(FromBody)] only works for enums"))?; + + let fields = match strukt.fields { Fields::Named(named) => ParsedFields::from_named(named.named)?, Fields::Unnamed(unnamed) => ParsedFields::from_unnamed(unnamed.unnamed)?, Fields::Unit => ParsedFields::from_unit()? @@ -115,14 +123,13 @@ fn expand(tokens : TokenStream) -> Result quote!(Self ( #(#field_names),* )) }; - // TODO: Replace the Err type with something more appropriate that implements Display Ok(quote! { impl #generics #krate::FromBody for #ident #generics where #where_clause { type Err = #krate::FromBodyNoError; - fn from_body(#body_ident : #krate::gotham::hyper::body::Bytes, #type_ident : #krate::Mime) -> Result + fn from_body(#body_ident : #krate::gotham::hyper::body::Bytes, #type_ident : #krate::Mime) -> Result { #block Ok(#ctor) diff --git a/gotham_restful_derive/src/openapi_type.rs b/gotham_restful_derive/src/openapi_type.rs index 319972c..355312f 100644 --- a/gotham_restful_derive/src/openapi_type.rs +++ b/gotham_restful_derive/src/openapi_type.rs @@ -6,14 +6,16 @@ use syn::{ spanned::Spanned, Attribute, AttributeArgs, + Data, + DataEnum, + DataStruct, + DeriveInput, Error, Field, Fields, Generics, GenericParam, - Item, - ItemEnum, - ItemStruct, + Ident, Lit, Meta, NestedMeta, @@ -23,13 +25,14 @@ use syn::{ pub fn expand(tokens : TokenStream) -> TokenStream { - let input = parse_macro_input!(tokens as Item); + let input = parse_macro_input!(tokens as DeriveInput); - let output = match input { - Item::Enum(item) => expand_enum(item), - Item::Struct(item) => expand_struct(item), - _ => Err(Error::new(input.span(), "derive(OpenapiType) not supported for this context")) + let output = match (input.ident, input.generics, input.attrs, input.data) { + (ident, generics, attrs, Data::Enum(inum)) => expand_enum(ident, generics, attrs, inum), + (ident, generics, attrs, Data::Struct(strukt)) => expand_struct(ident, generics, attrs, strukt), + (_, _, _, Data::Union(uni)) => Err(Error::new(uni.union_token.span(), "#[derive(OpenapiType)] only works for structs and enums")) }; + output .unwrap_or_else(|err| err.to_compile_error()) .into() @@ -127,14 +130,12 @@ fn expand_variant(variant : &Variant) -> Result }) } -fn expand_enum(input : ItemEnum) -> Result +fn expand_enum(ident : Ident, generics : Generics, attrs : Vec, input : DataEnum) -> Result { let krate = super::krate(); - let ident = input.ident; - let generics = input.generics; let where_clause = expand_where(&generics); - let attrs = parse_attributes(&input.attrs)?; + let attrs = parse_attributes(&attrs)?; let nullable = attrs.nullable; let name = match attrs.rename { Some(rename) => rename, @@ -229,14 +230,12 @@ fn expand_field(field : &Field) -> Result }}) } -pub fn expand_struct(input : ItemStruct) -> Result +pub fn expand_struct(ident : Ident, generics : Generics, attrs : Vec, input : DataStruct) -> Result { let krate = super::krate(); - let ident = input.ident; - let generics = input.generics; let where_clause = expand_where(&generics); - let attrs = parse_attributes(&input.attrs)?; + let attrs = parse_attributes(&attrs)?; let nullable = attrs.nullable; let name = match attrs.rename { Some(rename) => rename, diff --git a/gotham_restful_derive/src/request_body.rs b/gotham_restful_derive/src/request_body.rs index 7bc5d9d..f561a3a 100644 --- a/gotham_restful_derive/src/request_body.rs +++ b/gotham_restful_derive/src/request_body.rs @@ -7,10 +7,10 @@ use syn::{ parse::{Parse, ParseStream, Result as SynResult}, punctuated::Punctuated, token::Comma, + DeriveInput, Error, Generics, Ident, - ItemStruct, Path, parenthesized, parse_macro_input @@ -59,7 +59,7 @@ fn impl_openapi_type(ident : &Ident, generics : &Generics) -> TokenStream2 fn expand(tokens : TokenStream) -> Result { let krate = super::krate(); - let input = parse_macro_input::parse::(tokens)?; + let input = parse_macro_input::parse::(tokens)?; let ident = input.ident; let generics = input.generics; diff --git a/gotham_restful_derive/src/resource.rs b/gotham_restful_derive/src/resource.rs index fe2f47d..e618ebb 100644 --- a/gotham_restful_derive/src/resource.rs +++ b/gotham_restful_derive/src/resource.rs @@ -9,9 +9,9 @@ use syn::{ parse::{Parse, ParseStream}, punctuated::Punctuated, token::Comma, + DeriveInput, Error, Ident, - ItemStruct, parenthesized, parse_macro_input }; @@ -33,7 +33,7 @@ impl Parse for MethodList fn expand(tokens : TokenStream) -> Result { let krate = super::krate(); - let input = parse_macro_input::parse::(tokens)?; + let input = parse_macro_input::parse::(tokens)?; let ident = input.ident; let name = ident.to_string();