mirror of
https://gitlab.com/msrd0/gotham-restful.git
synced 2025-02-23 04:52:28 +00:00
simplify derive/macro code
This commit is contained in:
parent
7ef964b0a0
commit
110ef2be7a
8 changed files with 108 additions and 145 deletions
|
@ -1,5 +1,4 @@
|
|||
use proc_macro::TokenStream;
|
||||
use proc_macro2::TokenStream as TokenStream2;
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::{format_ident, quote};
|
||||
use std::cmp::min;
|
||||
use syn::{
|
||||
|
@ -10,16 +9,10 @@ use syn::{
|
|||
Field,
|
||||
Fields,
|
||||
Ident,
|
||||
Result,
|
||||
Type
|
||||
};
|
||||
|
||||
pub fn expand_from_body(tokens : TokenStream) -> TokenStream
|
||||
{
|
||||
expand(tokens)
|
||||
.unwrap_or_else(|err| err.to_compile_error())
|
||||
.into()
|
||||
}
|
||||
|
||||
struct ParsedFields
|
||||
{
|
||||
fields : Vec<(Ident, Type)>,
|
||||
|
@ -28,7 +21,7 @@ struct ParsedFields
|
|||
|
||||
impl ParsedFields
|
||||
{
|
||||
fn from_named<I>(fields : I) -> Result<Self, Error>
|
||||
fn from_named<I>(fields : I) -> Result<Self>
|
||||
where
|
||||
I : Iterator<Item = Field>
|
||||
{
|
||||
|
@ -36,7 +29,7 @@ impl ParsedFields
|
|||
Ok(Self { fields, named: true })
|
||||
}
|
||||
|
||||
fn from_unnamed<I>(fields : I) -> Result<Self, Error>
|
||||
fn from_unnamed<I>(fields : I) -> Result<Self>
|
||||
where
|
||||
I : Iterator<Item = Field>
|
||||
{
|
||||
|
@ -44,16 +37,15 @@ impl ParsedFields
|
|||
Ok(Self { fields, named: false })
|
||||
}
|
||||
|
||||
fn from_unit() -> Result<Self, Error>
|
||||
fn from_unit() -> Result<Self>
|
||||
{
|
||||
Ok(Self { fields: Vec::new(), named: false })
|
||||
}
|
||||
}
|
||||
|
||||
fn expand(tokens : TokenStream) -> Result<TokenStream2, Error>
|
||||
pub fn expand_from_body(input : DeriveInput) -> Result<TokenStream>
|
||||
{
|
||||
let krate = super::krate();
|
||||
let input : DeriveInput = syn::parse(tokens)?;
|
||||
let ident = input.ident;
|
||||
let generics = input.generics;
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use proc_macro::TokenStream;
|
||||
use proc_macro2::TokenStream as TokenStream2;
|
||||
use quote::quote;
|
||||
use syn::{parse_macro_input, parse_macro_input::ParseMacroInput, DeriveInput, Result};
|
||||
|
||||
mod util;
|
||||
|
||||
|
@ -16,95 +17,118 @@ mod resource_error;
|
|||
use resource_error::expand_resource_error;
|
||||
#[cfg(feature = "openapi")]
|
||||
mod openapi_type;
|
||||
#[cfg(feature = "openapi")]
|
||||
use openapi_type::expand_openapi_type;
|
||||
|
||||
#[inline]
|
||||
fn print_tokens(tokens : TokenStream) -> TokenStream
|
||||
fn print_tokens(tokens : TokenStream2) -> TokenStream
|
||||
{
|
||||
//eprintln!("{}", tokens);
|
||||
tokens
|
||||
tokens.into()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn expand_derive<F>(input : TokenStream, expand : F) -> TokenStream
|
||||
where
|
||||
F : FnOnce(DeriveInput) -> Result<TokenStream2>
|
||||
{
|
||||
print_tokens(expand(parse_macro_input!(input))
|
||||
.unwrap_or_else(|err| err.to_compile_error()))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn expand_macro<F, A, I>(attrs : TokenStream, item : TokenStream, expand : F) -> TokenStream
|
||||
where
|
||||
F : FnOnce(A, I) -> Result<TokenStream2>,
|
||||
A : ParseMacroInput,
|
||||
I : ParseMacroInput
|
||||
{
|
||||
print_tokens(expand(parse_macro_input!(attrs), parse_macro_input!(item))
|
||||
.unwrap_or_else(|err| err.to_compile_error()))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn krate() -> TokenStream2
|
||||
{
|
||||
quote!(::gotham_restful)
|
||||
}
|
||||
|
||||
#[proc_macro_derive(FromBody)]
|
||||
pub fn derive_from_body(tokens : TokenStream) -> TokenStream
|
||||
pub fn derive_from_body(input : TokenStream) -> TokenStream
|
||||
{
|
||||
print_tokens(expand_from_body(tokens))
|
||||
expand_derive(input, expand_from_body)
|
||||
}
|
||||
|
||||
#[cfg(feature = "openapi")]
|
||||
#[proc_macro_derive(OpenapiType, attributes(openapi))]
|
||||
pub fn derive_openapi_type(tokens : TokenStream) -> TokenStream
|
||||
pub fn derive_openapi_type(input : TokenStream) -> TokenStream
|
||||
{
|
||||
print_tokens(openapi_type::expand(tokens))
|
||||
expand_derive(input, expand_openapi_type)
|
||||
}
|
||||
|
||||
#[proc_macro_derive(RequestBody, attributes(supported_types))]
|
||||
pub fn derive_request_body(tokens : TokenStream) -> TokenStream
|
||||
pub fn derive_request_body(input : TokenStream) -> TokenStream
|
||||
{
|
||||
print_tokens(expand_request_body(tokens))
|
||||
expand_derive(input, expand_request_body)
|
||||
}
|
||||
|
||||
#[proc_macro_derive(Resource, attributes(rest_resource))]
|
||||
pub fn derive_resource(tokens : TokenStream) -> TokenStream
|
||||
pub fn derive_resource(input : TokenStream) -> TokenStream
|
||||
{
|
||||
print_tokens(expand_resource(tokens))
|
||||
expand_derive(input, expand_resource)
|
||||
}
|
||||
|
||||
#[proc_macro_derive(ResourceError, attributes(display, from, status))]
|
||||
pub fn derive_resource_error(tokens : TokenStream) -> TokenStream
|
||||
pub fn derive_resource_error(input : TokenStream) -> TokenStream
|
||||
{
|
||||
print_tokens(expand_resource_error(tokens))
|
||||
expand_derive(input, expand_resource_error)
|
||||
}
|
||||
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn rest_read_all(attr : TokenStream, item : TokenStream) -> TokenStream
|
||||
{
|
||||
print_tokens(expand_method(Method::ReadAll, attr, item))
|
||||
expand_macro(attr, item, |attr, item| expand_method(Method::ReadAll, attr, item))
|
||||
}
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn rest_read(attr : TokenStream, item : TokenStream) -> TokenStream
|
||||
{
|
||||
print_tokens(expand_method(Method::Read, attr, item))
|
||||
expand_macro(attr, item, |attr, item| expand_method(Method::Read, attr, item))
|
||||
}
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn rest_search(attr : TokenStream, item : TokenStream) -> TokenStream
|
||||
{
|
||||
print_tokens(expand_method(Method::Search, attr, item))
|
||||
expand_macro(attr, item, |attr, item| expand_method(Method::Search, attr, item))
|
||||
}
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn rest_create(attr : TokenStream, item : TokenStream) -> TokenStream
|
||||
{
|
||||
print_tokens(expand_method(Method::Create, attr, item))
|
||||
expand_macro(attr, item, |attr, item| expand_method(Method::Create, attr, item))
|
||||
}
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn rest_update_all(attr : TokenStream, item : TokenStream) -> TokenStream
|
||||
{
|
||||
print_tokens(expand_method(Method::UpdateAll, attr, item))
|
||||
expand_macro(attr, item, |attr, item| expand_method(Method::UpdateAll, attr, item))
|
||||
}
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn rest_update(attr : TokenStream, item : TokenStream) -> TokenStream
|
||||
{
|
||||
print_tokens(expand_method(Method::Update, attr, item))
|
||||
expand_macro(attr, item, |attr, item| expand_method(Method::Update, attr, item))
|
||||
}
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn rest_delete_all(attr : TokenStream, item : TokenStream) -> TokenStream
|
||||
{
|
||||
print_tokens(expand_method(Method::DeleteAll, attr, item))
|
||||
expand_macro(attr, item, |attr, item| expand_method(Method::DeleteAll, attr, item))
|
||||
}
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn rest_delete(attr : TokenStream, item : TokenStream) -> TokenStream
|
||||
{
|
||||
print_tokens(expand_method(Method::Delete, attr, item))
|
||||
expand_macro(attr, item, |attr, item| expand_method(Method::Delete, attr, item))
|
||||
}
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
use crate::util::CollectToResult;
|
||||
use heck::{CamelCase, SnakeCase};
|
||||
use proc_macro::TokenStream;
|
||||
use proc_macro2::{Ident, Span, TokenStream as TokenStream2};
|
||||
use proc_macro2::{Ident, Span, TokenStream};
|
||||
use quote::{format_ident, quote};
|
||||
use syn::{
|
||||
parse_macro_input,
|
||||
spanned::Spanned,
|
||||
Attribute,
|
||||
AttributeArgs,
|
||||
|
@ -16,6 +14,7 @@ use syn::{
|
|||
Meta,
|
||||
NestedMeta,
|
||||
PatType,
|
||||
Result,
|
||||
ReturnType,
|
||||
Type
|
||||
};
|
||||
|
@ -35,8 +34,9 @@ pub enum Method
|
|||
|
||||
impl FromStr for Method
|
||||
{
|
||||
type Err = String;
|
||||
fn from_str(str : &str) -> Result<Self, Self::Err>
|
||||
type Err = Error;
|
||||
|
||||
fn from_str(str : &str) -> Result<Self>
|
||||
{
|
||||
match str {
|
||||
"ReadAll" | "read_all" => Ok(Self::ReadAll),
|
||||
|
@ -47,7 +47,7 @@ impl FromStr for Method
|
|||
"Update" | "update" => Ok(Self::Update),
|
||||
"DeleteAll" | "delete_all" => Ok(Self::DeleteAll),
|
||||
"Delete" | "delete" => Ok(Self::Delete),
|
||||
_ => Err(format!("Unknown method: `{}'", str))
|
||||
_ => Err(Error::new(Span::call_site(), format!("Unknown method: `{}'", str)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -148,7 +148,7 @@ impl MethodArgumentType
|
|||
matches!(self, Self::AuthStatus(_) | Self::AuthStatusRef(_))
|
||||
}
|
||||
|
||||
fn quote_ty(&self) -> Option<TokenStream2>
|
||||
fn quote_ty(&self) -> Option<TokenStream>
|
||||
{
|
||||
match self {
|
||||
Self::MethodArg(ty) | Self::DatabaseConnection(ty) | Self::AuthStatus(ty) | Self::AuthStatusRef(ty) => Some(quote!(#ty)),
|
||||
|
@ -172,7 +172,7 @@ impl Spanned for MethodArgument
|
|||
}
|
||||
}
|
||||
|
||||
fn interpret_arg_ty(attrs : &[Attribute], name : &str, ty : Type) -> Result<MethodArgumentType, Error>
|
||||
fn interpret_arg_ty(attrs : &[Attribute], name : &str, ty : Type) -> Result<MethodArgumentType>
|
||||
{
|
||||
let attr = attrs.iter()
|
||||
.find(|arg| arg.path.segments.iter().any(|path| &path.ident.to_string() == "rest_arg"))
|
||||
|
@ -206,7 +206,7 @@ fn interpret_arg_ty(attrs : &[Attribute], name : &str, ty : Type) -> Result<Meth
|
|||
Ok(MethodArgumentType::MethodArg(ty))
|
||||
}
|
||||
|
||||
fn interpret_arg(index : usize, arg : &PatType) -> Result<MethodArgument, Error>
|
||||
fn interpret_arg(index : usize, arg : &PatType) -> Result<MethodArgument>
|
||||
{
|
||||
let pat = &arg.pat;
|
||||
let ident = format_ident!("arg{}", index);
|
||||
|
@ -217,7 +217,7 @@ fn interpret_arg(index : usize, arg : &PatType) -> Result<MethodArgument, Error>
|
|||
}
|
||||
|
||||
#[cfg(feature = "openapi")]
|
||||
fn expand_operation_id(attrs : &[NestedMeta]) -> TokenStream2
|
||||
fn expand_operation_id(attrs : &[NestedMeta]) -> TokenStream
|
||||
{
|
||||
let mut operation_id : Option<&Lit> = None;
|
||||
for meta in attrs
|
||||
|
@ -243,12 +243,12 @@ fn expand_operation_id(attrs : &[NestedMeta]) -> TokenStream2
|
|||
}
|
||||
|
||||
#[cfg(not(feature = "openapi"))]
|
||||
fn expand_operation_id(_ : &[NestedMeta]) -> TokenStream2
|
||||
fn expand_operation_id(_ : &[NestedMeta]) -> TokenStream
|
||||
{
|
||||
quote!()
|
||||
}
|
||||
|
||||
fn expand_wants_auth(attrs : &[NestedMeta], default : bool) -> TokenStream2
|
||||
fn expand_wants_auth(attrs : &[NestedMeta], default : bool) -> TokenStream
|
||||
{
|
||||
let default_lit = Lit::Bool(LitBool { value: default, span: Span::call_site() });
|
||||
let mut wants_auth = &default_lit;
|
||||
|
@ -272,21 +272,18 @@ fn expand_wants_auth(attrs : &[NestedMeta], default : bool) -> TokenStream2
|
|||
}
|
||||
|
||||
#[allow(clippy::comparison_chain)]
|
||||
fn expand(method : Method, attrs : TokenStream, item : TokenStream) -> Result<TokenStream2, Error>
|
||||
pub fn expand_method(method : Method, mut attrs : AttributeArgs, fun : ItemFn) -> Result<TokenStream>
|
||||
{
|
||||
let krate = super::krate();
|
||||
|
||||
// parse attributes
|
||||
// TODO this is not public api but syn currently doesn't offer another convenient way to parse AttributeArgs
|
||||
let mut method_attrs : AttributeArgs = parse_macro_input::parse(attrs)?;
|
||||
let resource_path = match method_attrs.remove(0) {
|
||||
let resource_path = match attrs.remove(0) {
|
||||
NestedMeta::Meta(Meta::Path(path)) => path,
|
||||
p => return Err(Error::new(p.span(), "Expected name of the Resource struct this method belongs to"))
|
||||
};
|
||||
let resource_name = resource_path.segments.last().map(|s| s.ident.to_string())
|
||||
.ok_or_else(|| Error::new(resource_path.span(), "Resource name must not be empty"))?;
|
||||
|
||||
let fun : ItemFn = syn::parse(item)?;
|
||||
let fun_ident = &fun.sig.ident;
|
||||
let fun_vis = &fun.vis;
|
||||
let fun_is_async = fun.sig.asyncness.is_some();
|
||||
|
@ -337,7 +334,7 @@ fn expand(method : Method, attrs : TokenStream, item : TokenStream) -> Result<To
|
|||
{
|
||||
return Err(Error::new(fun_ident.span(), "Too few arguments"));
|
||||
}
|
||||
let generics : Vec<TokenStream2> = generics_args.iter()
|
||||
let generics : Vec<TokenStream> = generics_args.iter()
|
||||
.map(|arg| arg.ty.quote_ty().unwrap())
|
||||
.zip(ty_names)
|
||||
.map(|(arg, name)| {
|
||||
|
@ -347,7 +344,7 @@ fn expand(method : Method, attrs : TokenStream, item : TokenStream) -> Result<To
|
|||
.collect();
|
||||
|
||||
// extract the definition of our method
|
||||
let mut args_def : Vec<TokenStream2> = args.iter()
|
||||
let mut args_def : Vec<TokenStream> = args.iter()
|
||||
.filter(|arg| (*arg).ty.is_method_arg())
|
||||
.map(|arg| {
|
||||
let ident = &arg.ident;
|
||||
|
@ -357,7 +354,7 @@ fn expand(method : Method, attrs : TokenStream, item : TokenStream) -> Result<To
|
|||
args_def.insert(0, quote!(mut #state_ident : #krate::State));
|
||||
|
||||
// extract the arguments to pass over to the supplied method
|
||||
let args_pass : Vec<TokenStream2> = args.iter().map(|arg| match (&arg.ty, &arg.ident) {
|
||||
let args_pass : Vec<TokenStream> = args.iter().map(|arg| match (&arg.ty, &arg.ident) {
|
||||
(MethodArgumentType::StateRef, _) => quote!(&#state_ident),
|
||||
(MethodArgumentType::StateMutRef, _) => quote!(&mut #state_ident),
|
||||
(MethodArgumentType::MethodArg(_), ident) => quote!(#ident),
|
||||
|
@ -417,8 +414,8 @@ fn expand(method : Method, attrs : TokenStream, item : TokenStream) -> Result<To
|
|||
}
|
||||
|
||||
// attribute generated code
|
||||
let operation_id = expand_operation_id(&method_attrs);
|
||||
let wants_auth = expand_wants_auth(&method_attrs, args.iter().any(|arg| (*arg).ty.is_auth_status()));
|
||||
let operation_id = expand_operation_id(&attrs);
|
||||
let wants_auth = expand_wants_auth(&attrs, args.iter().any(|arg| (*arg).ty.is_auth_status()));
|
||||
|
||||
// put everything together
|
||||
Ok(quote! {
|
||||
|
@ -466,10 +463,3 @@ fn expand(method : Method, attrs : TokenStream, item : TokenStream) -> Result<To
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn expand_method(method : Method, attrs : TokenStream, item : TokenStream) -> TokenStream
|
||||
{
|
||||
expand(method, attrs, item)
|
||||
.unwrap_or_else(|err| err.to_compile_error())
|
||||
.into()
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use crate::util::{CollectToResult, remove_parens};
|
||||
use proc_macro::TokenStream;
|
||||
use proc_macro2::TokenStream as TokenStream2;
|
||||
use proc_macro2::{Ident, TokenStream};
|
||||
use quote::quote;
|
||||
use syn::{
|
||||
parse_macro_input,
|
||||
|
@ -16,29 +15,23 @@ use syn::{
|
|||
Fields,
|
||||
Generics,
|
||||
GenericParam,
|
||||
Ident,
|
||||
Lit,
|
||||
Meta,
|
||||
NestedMeta,
|
||||
Result,
|
||||
Variant
|
||||
};
|
||||
|
||||
pub fn expand(tokens : TokenStream) -> TokenStream
|
||||
pub fn expand_openapi_type(input : DeriveInput) -> Result<TokenStream>
|
||||
{
|
||||
let input = parse_macro_input!(tokens as DeriveInput);
|
||||
|
||||
let output = match (input.ident, input.generics, input.attrs, input.data) {
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
fn expand_where(generics : &Generics) -> TokenStream2
|
||||
fn expand_where(generics : &Generics) -> TokenStream
|
||||
{
|
||||
if generics.params.is_empty()
|
||||
{
|
||||
|
@ -66,7 +59,7 @@ struct Attrs
|
|||
rename : Option<String>
|
||||
}
|
||||
|
||||
fn to_string(lit : &Lit) -> Result<String, Error>
|
||||
fn to_string(lit : &Lit) -> Result<String>
|
||||
{
|
||||
match lit {
|
||||
Lit::Str(str) => Ok(str.value()),
|
||||
|
@ -74,7 +67,7 @@ fn to_string(lit : &Lit) -> Result<String, Error>
|
|||
}
|
||||
}
|
||||
|
||||
fn to_bool(lit : &Lit) -> Result<bool, Error>
|
||||
fn to_bool(lit : &Lit) -> Result<bool>
|
||||
{
|
||||
match lit {
|
||||
Lit::Bool(bool) => Ok(bool.value),
|
||||
|
@ -82,7 +75,7 @@ fn to_bool(lit : &Lit) -> Result<bool, Error>
|
|||
}
|
||||
}
|
||||
|
||||
fn parse_attributes(input : &[Attribute]) -> Result<Attrs, Error>
|
||||
fn parse_attributes(input : &[Attribute]) -> Result<Attrs>
|
||||
{
|
||||
let mut parsed = Attrs::default();
|
||||
for attr in input
|
||||
|
@ -111,7 +104,7 @@ fn parse_attributes(input : &[Attribute]) -> Result<Attrs, Error>
|
|||
Ok(parsed)
|
||||
}
|
||||
|
||||
fn expand_variant(variant : &Variant) -> Result<TokenStream2, Error>
|
||||
fn expand_variant(variant : &Variant) -> Result<TokenStream>
|
||||
{
|
||||
if variant.fields != Fields::Unit
|
||||
{
|
||||
|
@ -131,7 +124,7 @@ fn expand_variant(variant : &Variant) -> Result<TokenStream2, Error>
|
|||
})
|
||||
}
|
||||
|
||||
fn expand_enum(ident : Ident, generics : Generics, attrs : Vec<Attribute>, input : DataEnum) -> Result<TokenStream2, Error>
|
||||
fn expand_enum(ident : Ident, generics : Generics, attrs : Vec<Attribute>, input : DataEnum) -> Result<TokenStream>
|
||||
{
|
||||
let krate = super::krate();
|
||||
let where_clause = expand_where(&generics);
|
||||
|
@ -176,7 +169,7 @@ fn expand_enum(ident : Ident, generics : Generics, attrs : Vec<Attribute>, input
|
|||
})
|
||||
}
|
||||
|
||||
fn expand_field(field : &Field) -> Result<TokenStream2, Error>
|
||||
fn expand_field(field : &Field) -> Result<TokenStream>
|
||||
{
|
||||
let ident = match &field.ident {
|
||||
Some(ident) => ident,
|
||||
|
@ -231,7 +224,7 @@ fn expand_field(field : &Field) -> Result<TokenStream2, Error>
|
|||
}})
|
||||
}
|
||||
|
||||
pub fn expand_struct(ident : Ident, generics : Generics, attrs : Vec<Attribute>, input : DataStruct) -> Result<TokenStream2, Error>
|
||||
fn expand_struct(ident : Ident, generics : Generics, attrs : Vec<Attribute>, input : DataStruct) -> Result<TokenStream>
|
||||
{
|
||||
let krate = super::krate();
|
||||
let where_clause = expand_where(&generics);
|
||||
|
@ -243,7 +236,7 @@ pub fn expand_struct(ident : Ident, generics : Generics, attrs : Vec<Attribute>,
|
|||
None => ident.to_string()
|
||||
};
|
||||
|
||||
let fields : Vec<TokenStream2> = match input.fields {
|
||||
let fields : Vec<TokenStream> = match input.fields {
|
||||
Fields::Named(named_fields) => {
|
||||
named_fields.named.iter()
|
||||
.map(expand_field)
|
||||
|
|
|
@ -1,17 +1,15 @@
|
|||
use crate::util::CollectToResult;
|
||||
use proc_macro::TokenStream;
|
||||
use proc_macro2::TokenStream as TokenStream2;
|
||||
use proc_macro2::{Ident, TokenStream};
|
||||
use quote::quote;
|
||||
use std::iter;
|
||||
use syn::{
|
||||
parenthesized,
|
||||
parse::{Parse, ParseStream, Result as SynResult},
|
||||
parse::{Parse, ParseStream},
|
||||
punctuated::Punctuated,
|
||||
DeriveInput,
|
||||
Error,
|
||||
Generics,
|
||||
Ident,
|
||||
Path,
|
||||
Result,
|
||||
Token
|
||||
};
|
||||
|
||||
|
@ -19,7 +17,7 @@ struct MimeList(Punctuated<Path, Token![,]>);
|
|||
|
||||
impl Parse for MimeList
|
||||
{
|
||||
fn parse(input: ParseStream) -> SynResult<Self>
|
||||
fn parse(input: ParseStream) -> Result<Self>
|
||||
{
|
||||
let content;
|
||||
let _paren = parenthesized!(content in input);
|
||||
|
@ -29,13 +27,13 @@ impl Parse for MimeList
|
|||
}
|
||||
|
||||
#[cfg(not(feature = "openapi"))]
|
||||
fn impl_openapi_type(_ident : &Ident, _generics : &Generics) -> TokenStream2
|
||||
fn impl_openapi_type(_ident : &Ident, _generics : &Generics) -> TokenStream
|
||||
{
|
||||
quote!()
|
||||
}
|
||||
|
||||
#[cfg(feature = "openapi")]
|
||||
fn impl_openapi_type(ident : &Ident, generics : &Generics) -> TokenStream2
|
||||
fn impl_openapi_type(ident : &Ident, generics : &Generics) -> TokenStream
|
||||
{
|
||||
let krate = super::krate();
|
||||
|
||||
|
@ -55,10 +53,9 @@ fn impl_openapi_type(ident : &Ident, generics : &Generics) -> TokenStream2
|
|||
}
|
||||
}
|
||||
|
||||
fn expand(tokens : TokenStream) -> Result<TokenStream2, Error>
|
||||
pub fn expand_request_body(input : DeriveInput) -> Result<TokenStream>
|
||||
{
|
||||
let krate = super::krate();
|
||||
let input : DeriveInput = syn::parse(tokens)?;
|
||||
let ident = input.ident;
|
||||
let generics = input.generics;
|
||||
|
||||
|
@ -66,7 +63,7 @@ fn expand(tokens : TokenStream) -> Result<TokenStream2, Error>
|
|||
.filter(|attr| attr.path.segments.iter().last().map(|segment| segment.ident.to_string()) == Some("supported_types".to_string()))
|
||||
.flat_map(|attr|
|
||||
syn::parse2::<MimeList>(attr.tokens)
|
||||
.map(|list| Box::new(list.0.into_iter().map(Ok)) as Box<dyn Iterator<Item = Result<Path, Error>>>)
|
||||
.map(|list| Box::new(list.0.into_iter().map(Ok)) as Box<dyn Iterator<Item = Result<Path>>>)
|
||||
.unwrap_or_else(|err| Box::new(iter::once(Err(err)))))
|
||||
.collect_to_result()?;
|
||||
|
||||
|
@ -90,10 +87,3 @@ fn expand(tokens : TokenStream) -> Result<TokenStream2, Error>
|
|||
#impl_openapi_type
|
||||
})
|
||||
}
|
||||
|
||||
pub fn expand_request_body(tokens : TokenStream) -> TokenStream
|
||||
{
|
||||
expand(tokens)
|
||||
.unwrap_or_else(|err| err.to_compile_error())
|
||||
.into()
|
||||
}
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
use crate::{
|
||||
method::Method,
|
||||
util::CollectToResult
|
||||
};
|
||||
use proc_macro::TokenStream;
|
||||
use proc_macro2::TokenStream as TokenStream2;
|
||||
use crate::{method::Method, util::CollectToResult};
|
||||
use proc_macro2::{Ident, TokenStream};
|
||||
use quote::quote;
|
||||
use syn::{
|
||||
parenthesized,
|
||||
|
@ -11,7 +7,7 @@ use syn::{
|
|||
punctuated::Punctuated,
|
||||
DeriveInput,
|
||||
Error,
|
||||
Ident,
|
||||
Result,
|
||||
Token
|
||||
};
|
||||
use std::{iter, str::FromStr};
|
||||
|
@ -20,7 +16,7 @@ struct MethodList(Punctuated<Ident, Token![,]>);
|
|||
|
||||
impl Parse for MethodList
|
||||
{
|
||||
fn parse(input: ParseStream) -> Result<Self, Error>
|
||||
fn parse(input: ParseStream) -> Result<Self>
|
||||
{
|
||||
let content;
|
||||
let _paren = parenthesized!(content in input);
|
||||
|
@ -29,10 +25,9 @@ impl Parse for MethodList
|
|||
}
|
||||
}
|
||||
|
||||
fn expand(tokens : TokenStream) -> Result<TokenStream2, Error>
|
||||
pub fn expand_resource(input : DeriveInput) -> Result<TokenStream>
|
||||
{
|
||||
let krate = super::krate();
|
||||
let input : DeriveInput = syn::parse(tokens)?;
|
||||
let ident = input.ident;
|
||||
let name = ident.to_string();
|
||||
|
||||
|
@ -46,7 +41,7 @@ fn expand(tokens : TokenStream) -> Result<TokenStream2, Error>
|
|||
let mod_ident = method.mod_ident(&name);
|
||||
let ident = method.setup_ident(&name);
|
||||
Ok(quote!(#mod_ident::#ident(&mut route);))
|
||||
})) as Box<dyn Iterator<Item = Result<TokenStream2, Error>>>,
|
||||
})) as Box<dyn Iterator<Item = Result<TokenStream>>>,
|
||||
Err(err) => Box::new(iter::once(Err(err)))
|
||||
}).collect_to_result()?;
|
||||
|
||||
|
@ -65,10 +60,3 @@ fn expand(tokens : TokenStream) -> Result<TokenStream2, Error>
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn expand_resource(tokens : TokenStream) -> TokenStream
|
||||
{
|
||||
expand(tokens)
|
||||
.unwrap_or_else(|err| err.to_compile_error())
|
||||
.into()
|
||||
}
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
use crate::util::{CollectToResult, remove_parens};
|
||||
use lazy_static::lazy_static;
|
||||
use proc_macro::TokenStream;
|
||||
use proc_macro2::TokenStream as TokenStream2;
|
||||
use proc_macro2::{Ident, TokenStream};
|
||||
use quote::{format_ident, quote};
|
||||
use regex::Regex;
|
||||
use std::iter;
|
||||
use syn::{
|
||||
parse_macro_input,
|
||||
spanned::Spanned,
|
||||
Attribute,
|
||||
Data,
|
||||
|
@ -14,10 +12,10 @@ use syn::{
|
|||
Error,
|
||||
Fields,
|
||||
GenericParam,
|
||||
Ident,
|
||||
LitStr,
|
||||
Path,
|
||||
PathSegment,
|
||||
Result,
|
||||
Type,
|
||||
Variant
|
||||
};
|
||||
|
@ -40,7 +38,7 @@ struct ErrorVariant
|
|||
display : Option<LitStr>
|
||||
}
|
||||
|
||||
fn process_variant(variant : Variant) -> Result<ErrorVariant, Error>
|
||||
fn process_variant(variant : Variant) -> Result<ErrorVariant>
|
||||
{
|
||||
let status = match variant.attrs.iter()
|
||||
.find(|attr| attr.path.segments.iter().last().map(|segment| segment.ident.to_string()) == Some("status".to_string()))
|
||||
|
@ -114,7 +112,7 @@ lazy_static! {
|
|||
|
||||
impl ErrorVariant
|
||||
{
|
||||
fn fields_pat(&self) -> TokenStream2
|
||||
fn fields_pat(&self) -> TokenStream
|
||||
{
|
||||
let mut fields = self.fields.iter().map(|field| &field.ident).peekable();
|
||||
if fields.peek().is_none() {
|
||||
|
@ -126,7 +124,7 @@ impl ErrorVariant
|
|||
}
|
||||
}
|
||||
|
||||
fn to_display_match_arm(&self, formatter_ident : &Ident, enum_ident : &Ident) -> Result<TokenStream2, Error>
|
||||
fn to_display_match_arm(&self, formatter_ident : &Ident, enum_ident : &Ident) -> Result<TokenStream>
|
||||
{
|
||||
let ident = &self.ident;
|
||||
let display = self.display.as_ref().ok_or_else(|| Error::new(self.ident.span(), "Missing display string for this variant"))?;
|
||||
|
@ -142,7 +140,7 @@ impl ErrorVariant
|
|||
})
|
||||
}
|
||||
|
||||
fn into_match_arm(self, krate : &TokenStream2, enum_ident : &Ident) -> TokenStream2
|
||||
fn into_match_arm(self, krate : &TokenStream, enum_ident : &Ident) -> TokenStream
|
||||
{
|
||||
let ident = &self.ident;
|
||||
let fields_pat = self.fields_pat();
|
||||
|
@ -177,7 +175,7 @@ impl ErrorVariant
|
|||
}
|
||||
}
|
||||
|
||||
fn were(&self) -> Option<TokenStream2>
|
||||
fn were(&self) -> Option<TokenStream>
|
||||
{
|
||||
match self.from_ty.as_ref() {
|
||||
Some((_, ty)) => Some(quote!( #ty : ::std::error::Error )),
|
||||
|
@ -186,10 +184,9 @@ impl ErrorVariant
|
|||
}
|
||||
}
|
||||
|
||||
fn expand(tokens : TokenStream) -> Result<TokenStream2, Error>
|
||||
pub fn expand_resource_error(input : DeriveInput) -> Result<TokenStream>
|
||||
{
|
||||
let krate = super::krate();
|
||||
let input = parse_macro_input::parse::<DeriveInput>(tokens)?;
|
||||
let ident = input.ident;
|
||||
let generics = input.generics;
|
||||
|
||||
|
@ -228,7 +225,7 @@ fn expand(tokens : TokenStream) -> Result<TokenStream2, Error>
|
|||
})
|
||||
};
|
||||
|
||||
let mut from_impls : Vec<TokenStream2> = Vec::new();
|
||||
let mut from_impls : Vec<TokenStream> = Vec::new();
|
||||
|
||||
for var in &variants
|
||||
{
|
||||
|
@ -290,10 +287,3 @@ fn expand(tokens : TokenStream) -> Result<TokenStream2, Error>
|
|||
#( #from_impls )*
|
||||
})
|
||||
}
|
||||
|
||||
pub fn expand_resource_error(tokens : TokenStream) -> TokenStream
|
||||
{
|
||||
expand(tokens)
|
||||
.unwrap_or_else(|err| err.to_compile_error())
|
||||
.into()
|
||||
}
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
use proc_macro2::{
|
||||
Delimiter,
|
||||
TokenStream as TokenStream2,
|
||||
TokenTree
|
||||
};
|
||||
use proc_macro2::{Delimiter, TokenStream, TokenTree};
|
||||
use std::iter;
|
||||
use syn::Error;
|
||||
|
||||
|
@ -33,7 +29,7 @@ where
|
|||
}
|
||||
|
||||
|
||||
pub fn remove_parens(input : TokenStream2) -> TokenStream2
|
||||
pub fn remove_parens(input : TokenStream) -> TokenStream
|
||||
{
|
||||
let iter = input.into_iter().flat_map(|tt| {
|
||||
if let TokenTree::Group(group) = &tt
|
||||
|
|
Loading…
Add table
Reference in a new issue