diff --git a/actix-web-codegen/src/lib.rs b/actix-web-codegen/src/lib.rs index 0a727ed6..affb4dfe 100644 --- a/actix-web-codegen/src/lib.rs +++ b/actix-web-codegen/src/lib.rs @@ -45,6 +45,8 @@ extern crate proc_macro; mod route; use proc_macro::TokenStream; +use quote::ToTokens; +use route::Route; use syn::parse_macro_input; /// Creates route handler with `GET` method guard. @@ -58,11 +60,10 @@ use syn::parse_macro_input; #[proc_macro_attribute] pub fn get(args: TokenStream, input: TokenStream) -> TokenStream { let args = parse_macro_input!(args as syn::AttributeArgs); - let gen = match route::Route::new(args, input, route::GuardType::Get) { - Ok(gen) => gen, - Err(err) => return err.to_compile_error().into(), - }; - gen.generate() + match Route::new(args, input, route::GuardType::Get) { + Ok(route) => route.into_token_stream().into(), + Err(err) => err.to_compile_error().into(), + } } /// Creates route handler with `POST` method guard. @@ -73,11 +74,10 @@ pub fn get(args: TokenStream, input: TokenStream) -> TokenStream { #[proc_macro_attribute] pub fn post(args: TokenStream, input: TokenStream) -> TokenStream { let args = parse_macro_input!(args as syn::AttributeArgs); - let gen = match route::Route::new(args, input, route::GuardType::Post) { - Ok(gen) => gen, - Err(err) => return err.to_compile_error().into(), - }; - gen.generate() + match Route::new(args, input, route::GuardType::Post) { + Ok(route) => route.into_token_stream().into(), + Err(err) => err.to_compile_error().into(), + } } /// Creates route handler with `PUT` method guard. @@ -88,11 +88,10 @@ pub fn post(args: TokenStream, input: TokenStream) -> TokenStream { #[proc_macro_attribute] pub fn put(args: TokenStream, input: TokenStream) -> TokenStream { let args = parse_macro_input!(args as syn::AttributeArgs); - let gen = match route::Route::new(args, input, route::GuardType::Put) { - Ok(gen) => gen, - Err(err) => return err.to_compile_error().into(), - }; - gen.generate() + match Route::new(args, input, route::GuardType::Put) { + Ok(route) => route.into_token_stream().into(), + Err(err) => err.to_compile_error().into(), + } } /// Creates route handler with `DELETE` method guard. @@ -103,11 +102,10 @@ pub fn put(args: TokenStream, input: TokenStream) -> TokenStream { #[proc_macro_attribute] pub fn delete(args: TokenStream, input: TokenStream) -> TokenStream { let args = parse_macro_input!(args as syn::AttributeArgs); - let gen = match route::Route::new(args, input, route::GuardType::Delete) { - Ok(gen) => gen, - Err(err) => return err.to_compile_error().into(), - }; - gen.generate() + match Route::new(args, input, route::GuardType::Delete) { + Ok(route) => route.into_token_stream().into(), + Err(err) => err.to_compile_error().into(), + } } /// Creates route handler with `HEAD` method guard. @@ -118,11 +116,10 @@ pub fn delete(args: TokenStream, input: TokenStream) -> TokenStream { #[proc_macro_attribute] pub fn head(args: TokenStream, input: TokenStream) -> TokenStream { let args = parse_macro_input!(args as syn::AttributeArgs); - let gen = match route::Route::new(args, input, route::GuardType::Head) { - Ok(gen) => gen, - Err(err) => return err.to_compile_error().into(), - }; - gen.generate() + match Route::new(args, input, route::GuardType::Head) { + Ok(route) => route.into_token_stream().into(), + Err(err) => err.to_compile_error().into(), + } } /// Creates route handler with `CONNECT` method guard. @@ -133,11 +130,10 @@ pub fn head(args: TokenStream, input: TokenStream) -> TokenStream { #[proc_macro_attribute] pub fn connect(args: TokenStream, input: TokenStream) -> TokenStream { let args = parse_macro_input!(args as syn::AttributeArgs); - let gen = match route::Route::new(args, input, route::GuardType::Connect) { - Ok(gen) => gen, - Err(err) => return err.to_compile_error().into(), - }; - gen.generate() + match Route::new(args, input, route::GuardType::Connect) { + Ok(route) => route.into_token_stream().into(), + Err(err) => err.to_compile_error().into(), + } } /// Creates route handler with `OPTIONS` method guard. @@ -148,11 +144,10 @@ pub fn connect(args: TokenStream, input: TokenStream) -> TokenStream { #[proc_macro_attribute] pub fn options(args: TokenStream, input: TokenStream) -> TokenStream { let args = parse_macro_input!(args as syn::AttributeArgs); - let gen = match route::Route::new(args, input, route::GuardType::Options) { - Ok(gen) => gen, - Err(err) => return err.to_compile_error().into(), - }; - gen.generate() + match Route::new(args, input, route::GuardType::Options) { + Ok(route) => route.into_token_stream().into(), + Err(err) => err.to_compile_error().into(), + } } /// Creates route handler with `TRACE` method guard. @@ -163,11 +158,10 @@ pub fn options(args: TokenStream, input: TokenStream) -> TokenStream { #[proc_macro_attribute] pub fn trace(args: TokenStream, input: TokenStream) -> TokenStream { let args = parse_macro_input!(args as syn::AttributeArgs); - let gen = match route::Route::new(args, input, route::GuardType::Trace) { - Ok(gen) => gen, - Err(err) => return err.to_compile_error().into(), - }; - gen.generate() + match Route::new(args, input, route::GuardType::Trace) { + Ok(route) => route.into_token_stream().into(), + Err(err) => err.to_compile_error().into(), + } } /// Creates route handler with `PATCH` method guard. @@ -178,9 +172,8 @@ pub fn trace(args: TokenStream, input: TokenStream) -> TokenStream { #[proc_macro_attribute] pub fn patch(args: TokenStream, input: TokenStream) -> TokenStream { let args = parse_macro_input!(args as syn::AttributeArgs); - let gen = match route::Route::new(args, input, route::GuardType::Patch) { - Ok(gen) => gen, - Err(err) => return err.to_compile_error().into(), - }; - gen.generate() + match Route::new(args, input, route::GuardType::Patch) { + Ok(route) => route.into_token_stream().into(), + Err(err) => err.to_compile_error().into(), + } } diff --git a/actix-web-codegen/src/route.rs b/actix-web-codegen/src/route.rs index 60b82959..341329ea 100644 --- a/actix-web-codegen/src/route.rs +++ b/actix-web-codegen/src/route.rs @@ -2,7 +2,7 @@ extern crate proc_macro; use proc_macro::TokenStream; use proc_macro2::{Span, TokenStream as TokenStream2}; -use quote::{quote, ToTokens, TokenStreamExt}; +use quote::{format_ident, quote, ToTokens, TokenStreamExt}; use syn::{AttributeArgs, Ident, NestedMeta}; enum ResourceType { @@ -12,11 +12,7 @@ enum ResourceType { impl ToTokens for ResourceType { fn to_tokens(&self, stream: &mut TokenStream2) { - let ident = match self { - ResourceType::Async => "to", - ResourceType::Sync => "to", - }; - let ident = Ident::new(ident, Span::call_site()); + let ident = format_ident!("to"); stream.append(ident); } } @@ -52,8 +48,7 @@ impl GuardType { impl ToTokens for GuardType { fn to_tokens(&self, stream: &mut TokenStream2) { - let ident = self.as_str(); - let ident = Ident::new(ident, Span::call_site()); + let ident = Ident::new(self.as_str(), Span::call_site()); stream.append(ident); } } @@ -93,12 +88,12 @@ impl Args { } else { return Err(syn::Error::new_spanned( nv.path, - "Unknown attribute key is specified. Allowed: guard", + "Unknown attribute key is specified. Allowed: guard.", )); } } arg => { - return Err(syn::Error::new_spanned(arg, "Unknown attribute")); + return Err(syn::Error::new_spanned(arg, "Unknown attribute.")); } } } @@ -181,15 +176,18 @@ impl Route { guard, }) } +} - pub fn generate(&self) -> TokenStream { - let name = &self.name; +impl ToTokens for Route { + fn to_tokens(&self, output: &mut TokenStream2) { + let Self { + name, + guard, + ast, + args: Args { path, guards }, + resource_type, + } = self; let resource_name = name.to_string(); - let guard = &self.guard; - let ast = &self.ast; - let path = &self.args.path; - let extra_guards = &self.args.guards; - let resource_type = &self.resource_type; let stream = quote! { #[allow(non_camel_case_types, missing_docs)] pub struct #name; @@ -200,13 +198,14 @@ impl Route { let __resource = actix_web::Resource::new(#path) .name(#resource_name) .guard(actix_web::guard::#guard()) - #(.guard(actix_web::guard::fn_guard(#extra_guards)))* + #(.guard(actix_web::guard::fn_guard(#guards)))* .#resource_type(#name); actix_web::dev::HttpServiceFactory::register(__resource, __config) } } }; - stream.into() + + output.extend(stream); } }