1
0
Fork 0
mirror of https://gitlab.com/msrd0/gotham-restful.git synced 2025-02-23 04:52:28 +00:00

use DeriveInput for input into derive macros from syn

This commit is contained in:
Dominic 2020-05-03 23:10:19 +02:00
parent f7157dcf62
commit da30f34d97
Signed by: msrd0
GPG key ID: DCC8C247452E98F9
5 changed files with 32 additions and 26 deletions

View file

@ -22,7 +22,7 @@ lazy_static = "1.4.0"
proc-macro2 = "1.0.10" proc-macro2 = "1.0.10"
quote = "1.0.3" quote = "1.0.3"
regex = "1.3.7" regex = "1.3.7"
syn = { version = "1.0.17", features = ["extra-traits", "full"] } syn = "1.0.18"
[features] [features]
default = [] default = []

View file

@ -4,12 +4,14 @@ use quote::{format_ident, quote};
use std::cmp::min; use std::cmp::min;
use syn::{ use syn::{
punctuated::Punctuated, punctuated::Punctuated,
spanned::Spanned,
token::Comma, token::Comma,
Data,
DeriveInput,
Error, Error,
Field, Field,
Fields, Fields,
Ident, Ident,
ItemStruct,
Type, Type,
parse_macro_input parse_macro_input
}; };
@ -50,11 +52,17 @@ impl ParsedFields
fn expand(tokens : TokenStream) -> Result<TokenStream2, Error> fn expand(tokens : TokenStream) -> Result<TokenStream2, Error>
{ {
let krate = super::krate(); let krate = super::krate();
let input = parse_macro_input::parse::<ItemStruct>(tokens)?; let input = parse_macro_input::parse::<DeriveInput>(tokens)?;
let ident = input.ident; let ident = input.ident;
let generics = input.generics; 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::Named(named) => ParsedFields::from_named(named.named)?,
Fields::Unnamed(unnamed) => ParsedFields::from_unnamed(unnamed.unnamed)?, Fields::Unnamed(unnamed) => ParsedFields::from_unnamed(unnamed.unnamed)?,
Fields::Unit => ParsedFields::from_unit()? Fields::Unit => ParsedFields::from_unit()?
@ -115,14 +123,13 @@ fn expand(tokens : TokenStream) -> Result<TokenStream2, Error>
quote!(Self ( #(#field_names),* )) quote!(Self ( #(#field_names),* ))
}; };
// TODO: Replace the Err type with something more appropriate that implements Display
Ok(quote! { Ok(quote! {
impl #generics #krate::FromBody for #ident #generics impl #generics #krate::FromBody for #ident #generics
where #where_clause where #where_clause
{ {
type Err = #krate::FromBodyNoError; type Err = #krate::FromBodyNoError;
fn from_body(#body_ident : #krate::gotham::hyper::body::Bytes, #type_ident : #krate::Mime) -> Result<Self, Self::Err> fn from_body(#body_ident : #krate::gotham::hyper::body::Bytes, #type_ident : #krate::Mime) -> Result<Self, #krate::FromBodyNoError>
{ {
#block #block
Ok(#ctor) Ok(#ctor)

View file

@ -6,14 +6,16 @@ use syn::{
spanned::Spanned, spanned::Spanned,
Attribute, Attribute,
AttributeArgs, AttributeArgs,
Data,
DataEnum,
DataStruct,
DeriveInput,
Error, Error,
Field, Field,
Fields, Fields,
Generics, Generics,
GenericParam, GenericParam,
Item, Ident,
ItemEnum,
ItemStruct,
Lit, Lit,
Meta, Meta,
NestedMeta, NestedMeta,
@ -23,13 +25,14 @@ use syn::{
pub fn expand(tokens : TokenStream) -> TokenStream 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 { let output = match (input.ident, input.generics, input.attrs, input.data) {
Item::Enum(item) => expand_enum(item), (ident, generics, attrs, Data::Enum(inum)) => expand_enum(ident, generics, attrs, inum),
Item::Struct(item) => expand_struct(item), (ident, generics, attrs, Data::Struct(strukt)) => expand_struct(ident, generics, attrs, strukt),
_ => Err(Error::new(input.span(), "derive(OpenapiType) not supported for this context")) (_, _, _, Data::Union(uni)) => Err(Error::new(uni.union_token.span(), "#[derive(OpenapiType)] only works for structs and enums"))
}; };
output output
.unwrap_or_else(|err| err.to_compile_error()) .unwrap_or_else(|err| err.to_compile_error())
.into() .into()
@ -127,14 +130,12 @@ fn expand_variant(variant : &Variant) -> Result<TokenStream2, Error>
}) })
} }
fn expand_enum(input : ItemEnum) -> Result<TokenStream2, Error> fn expand_enum(ident : Ident, generics : Generics, attrs : Vec<Attribute>, input : DataEnum) -> Result<TokenStream2, Error>
{ {
let krate = super::krate(); let krate = super::krate();
let ident = input.ident;
let generics = input.generics;
let where_clause = expand_where(&generics); let where_clause = expand_where(&generics);
let attrs = parse_attributes(&input.attrs)?; let attrs = parse_attributes(&attrs)?;
let nullable = attrs.nullable; let nullable = attrs.nullable;
let name = match attrs.rename { let name = match attrs.rename {
Some(rename) => rename, Some(rename) => rename,
@ -229,14 +230,12 @@ fn expand_field(field : &Field) -> Result<TokenStream2, Error>
}}) }})
} }
pub fn expand_struct(input : ItemStruct) -> Result<TokenStream2, Error> pub fn expand_struct(ident : Ident, generics : Generics, attrs : Vec<Attribute>, input : DataStruct) -> Result<TokenStream2, Error>
{ {
let krate = super::krate(); let krate = super::krate();
let ident = input.ident;
let generics = input.generics;
let where_clause = expand_where(&generics); let where_clause = expand_where(&generics);
let attrs = parse_attributes(&input.attrs)?; let attrs = parse_attributes(&attrs)?;
let nullable = attrs.nullable; let nullable = attrs.nullable;
let name = match attrs.rename { let name = match attrs.rename {
Some(rename) => rename, Some(rename) => rename,

View file

@ -7,10 +7,10 @@ use syn::{
parse::{Parse, ParseStream, Result as SynResult}, parse::{Parse, ParseStream, Result as SynResult},
punctuated::Punctuated, punctuated::Punctuated,
token::Comma, token::Comma,
DeriveInput,
Error, Error,
Generics, Generics,
Ident, Ident,
ItemStruct,
Path, Path,
parenthesized, parenthesized,
parse_macro_input parse_macro_input
@ -59,7 +59,7 @@ fn impl_openapi_type(ident : &Ident, generics : &Generics) -> TokenStream2
fn expand(tokens : TokenStream) -> Result<TokenStream2, Error> fn expand(tokens : TokenStream) -> Result<TokenStream2, Error>
{ {
let krate = super::krate(); let krate = super::krate();
let input = parse_macro_input::parse::<ItemStruct>(tokens)?; let input = parse_macro_input::parse::<DeriveInput>(tokens)?;
let ident = input.ident; let ident = input.ident;
let generics = input.generics; let generics = input.generics;

View file

@ -9,9 +9,9 @@ use syn::{
parse::{Parse, ParseStream}, parse::{Parse, ParseStream},
punctuated::Punctuated, punctuated::Punctuated,
token::Comma, token::Comma,
DeriveInput,
Error, Error,
Ident, Ident,
ItemStruct,
parenthesized, parenthesized,
parse_macro_input parse_macro_input
}; };
@ -33,7 +33,7 @@ impl Parse for MethodList
fn expand(tokens : TokenStream) -> Result<TokenStream2, Error> fn expand(tokens : TokenStream) -> Result<TokenStream2, Error>
{ {
let krate = super::krate(); let krate = super::krate();
let input = parse_macro_input::parse::<ItemStruct>(tokens)?; let input = parse_macro_input::parse::<DeriveInput>(tokens)?;
let ident = input.ident; let ident = input.ident;
let name = ident.to_string(); let name = ident.to_string();