1
0
Fork 0
mirror of https://github.com/actix/actix-web.git synced 2024-07-03 20:45:46 +00:00

Refactored macros (#1333)

Co-authored-by: Yuki Okushi <huyuumi.dev@gmail.com>
This commit is contained in:
Oleg Nosov 2020-03-15 01:23:28 +03:00 committed by GitHub
parent 4875dfbec7
commit c67e4c1fe8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 56 additions and 64 deletions

View file

@ -45,6 +45,8 @@ extern crate proc_macro;
mod route; mod route;
use proc_macro::TokenStream; use proc_macro::TokenStream;
use quote::ToTokens;
use route::Route;
use syn::parse_macro_input; use syn::parse_macro_input;
/// Creates route handler with `GET` method guard. /// Creates route handler with `GET` method guard.
@ -58,11 +60,10 @@ use syn::parse_macro_input;
#[proc_macro_attribute] #[proc_macro_attribute]
pub fn get(args: TokenStream, input: TokenStream) -> TokenStream { pub fn get(args: TokenStream, input: TokenStream) -> TokenStream {
let args = parse_macro_input!(args as syn::AttributeArgs); let args = parse_macro_input!(args as syn::AttributeArgs);
let gen = match route::Route::new(args, input, route::GuardType::Get) { match Route::new(args, input, route::GuardType::Get) {
Ok(gen) => gen, Ok(route) => route.into_token_stream().into(),
Err(err) => return err.to_compile_error().into(), Err(err) => err.to_compile_error().into(),
}; }
gen.generate()
} }
/// Creates route handler with `POST` method guard. /// Creates route handler with `POST` method guard.
@ -73,11 +74,10 @@ pub fn get(args: TokenStream, input: TokenStream) -> TokenStream {
#[proc_macro_attribute] #[proc_macro_attribute]
pub fn post(args: TokenStream, input: TokenStream) -> TokenStream { pub fn post(args: TokenStream, input: TokenStream) -> TokenStream {
let args = parse_macro_input!(args as syn::AttributeArgs); let args = parse_macro_input!(args as syn::AttributeArgs);
let gen = match route::Route::new(args, input, route::GuardType::Post) { match Route::new(args, input, route::GuardType::Post) {
Ok(gen) => gen, Ok(route) => route.into_token_stream().into(),
Err(err) => return err.to_compile_error().into(), Err(err) => err.to_compile_error().into(),
}; }
gen.generate()
} }
/// Creates route handler with `PUT` method guard. /// Creates route handler with `PUT` method guard.
@ -88,11 +88,10 @@ pub fn post(args: TokenStream, input: TokenStream) -> TokenStream {
#[proc_macro_attribute] #[proc_macro_attribute]
pub fn put(args: TokenStream, input: TokenStream) -> TokenStream { pub fn put(args: TokenStream, input: TokenStream) -> TokenStream {
let args = parse_macro_input!(args as syn::AttributeArgs); let args = parse_macro_input!(args as syn::AttributeArgs);
let gen = match route::Route::new(args, input, route::GuardType::Put) { match Route::new(args, input, route::GuardType::Put) {
Ok(gen) => gen, Ok(route) => route.into_token_stream().into(),
Err(err) => return err.to_compile_error().into(), Err(err) => err.to_compile_error().into(),
}; }
gen.generate()
} }
/// Creates route handler with `DELETE` method guard. /// Creates route handler with `DELETE` method guard.
@ -103,11 +102,10 @@ pub fn put(args: TokenStream, input: TokenStream) -> TokenStream {
#[proc_macro_attribute] #[proc_macro_attribute]
pub fn delete(args: TokenStream, input: TokenStream) -> TokenStream { pub fn delete(args: TokenStream, input: TokenStream) -> TokenStream {
let args = parse_macro_input!(args as syn::AttributeArgs); let args = parse_macro_input!(args as syn::AttributeArgs);
let gen = match route::Route::new(args, input, route::GuardType::Delete) { match Route::new(args, input, route::GuardType::Delete) {
Ok(gen) => gen, Ok(route) => route.into_token_stream().into(),
Err(err) => return err.to_compile_error().into(), Err(err) => err.to_compile_error().into(),
}; }
gen.generate()
} }
/// Creates route handler with `HEAD` method guard. /// Creates route handler with `HEAD` method guard.
@ -118,11 +116,10 @@ pub fn delete(args: TokenStream, input: TokenStream) -> TokenStream {
#[proc_macro_attribute] #[proc_macro_attribute]
pub fn head(args: TokenStream, input: TokenStream) -> TokenStream { pub fn head(args: TokenStream, input: TokenStream) -> TokenStream {
let args = parse_macro_input!(args as syn::AttributeArgs); let args = parse_macro_input!(args as syn::AttributeArgs);
let gen = match route::Route::new(args, input, route::GuardType::Head) { match Route::new(args, input, route::GuardType::Head) {
Ok(gen) => gen, Ok(route) => route.into_token_stream().into(),
Err(err) => return err.to_compile_error().into(), Err(err) => err.to_compile_error().into(),
}; }
gen.generate()
} }
/// Creates route handler with `CONNECT` method guard. /// Creates route handler with `CONNECT` method guard.
@ -133,11 +130,10 @@ pub fn head(args: TokenStream, input: TokenStream) -> TokenStream {
#[proc_macro_attribute] #[proc_macro_attribute]
pub fn connect(args: TokenStream, input: TokenStream) -> TokenStream { pub fn connect(args: TokenStream, input: TokenStream) -> TokenStream {
let args = parse_macro_input!(args as syn::AttributeArgs); let args = parse_macro_input!(args as syn::AttributeArgs);
let gen = match route::Route::new(args, input, route::GuardType::Connect) { match Route::new(args, input, route::GuardType::Connect) {
Ok(gen) => gen, Ok(route) => route.into_token_stream().into(),
Err(err) => return err.to_compile_error().into(), Err(err) => err.to_compile_error().into(),
}; }
gen.generate()
} }
/// Creates route handler with `OPTIONS` method guard. /// Creates route handler with `OPTIONS` method guard.
@ -148,11 +144,10 @@ pub fn connect(args: TokenStream, input: TokenStream) -> TokenStream {
#[proc_macro_attribute] #[proc_macro_attribute]
pub fn options(args: TokenStream, input: TokenStream) -> TokenStream { pub fn options(args: TokenStream, input: TokenStream) -> TokenStream {
let args = parse_macro_input!(args as syn::AttributeArgs); let args = parse_macro_input!(args as syn::AttributeArgs);
let gen = match route::Route::new(args, input, route::GuardType::Options) { match Route::new(args, input, route::GuardType::Options) {
Ok(gen) => gen, Ok(route) => route.into_token_stream().into(),
Err(err) => return err.to_compile_error().into(), Err(err) => err.to_compile_error().into(),
}; }
gen.generate()
} }
/// Creates route handler with `TRACE` method guard. /// Creates route handler with `TRACE` method guard.
@ -163,11 +158,10 @@ pub fn options(args: TokenStream, input: TokenStream) -> TokenStream {
#[proc_macro_attribute] #[proc_macro_attribute]
pub fn trace(args: TokenStream, input: TokenStream) -> TokenStream { pub fn trace(args: TokenStream, input: TokenStream) -> TokenStream {
let args = parse_macro_input!(args as syn::AttributeArgs); let args = parse_macro_input!(args as syn::AttributeArgs);
let gen = match route::Route::new(args, input, route::GuardType::Trace) { match Route::new(args, input, route::GuardType::Trace) {
Ok(gen) => gen, Ok(route) => route.into_token_stream().into(),
Err(err) => return err.to_compile_error().into(), Err(err) => err.to_compile_error().into(),
}; }
gen.generate()
} }
/// Creates route handler with `PATCH` method guard. /// Creates route handler with `PATCH` method guard.
@ -178,9 +172,8 @@ pub fn trace(args: TokenStream, input: TokenStream) -> TokenStream {
#[proc_macro_attribute] #[proc_macro_attribute]
pub fn patch(args: TokenStream, input: TokenStream) -> TokenStream { pub fn patch(args: TokenStream, input: TokenStream) -> TokenStream {
let args = parse_macro_input!(args as syn::AttributeArgs); let args = parse_macro_input!(args as syn::AttributeArgs);
let gen = match route::Route::new(args, input, route::GuardType::Patch) { match Route::new(args, input, route::GuardType::Patch) {
Ok(gen) => gen, Ok(route) => route.into_token_stream().into(),
Err(err) => return err.to_compile_error().into(), Err(err) => err.to_compile_error().into(),
}; }
gen.generate()
} }

View file

@ -2,7 +2,7 @@ extern crate proc_macro;
use proc_macro::TokenStream; use proc_macro::TokenStream;
use proc_macro2::{Span, TokenStream as TokenStream2}; use proc_macro2::{Span, TokenStream as TokenStream2};
use quote::{quote, ToTokens, TokenStreamExt}; use quote::{format_ident, quote, ToTokens, TokenStreamExt};
use syn::{AttributeArgs, Ident, NestedMeta}; use syn::{AttributeArgs, Ident, NestedMeta};
enum ResourceType { enum ResourceType {
@ -12,11 +12,7 @@ enum ResourceType {
impl ToTokens for ResourceType { impl ToTokens for ResourceType {
fn to_tokens(&self, stream: &mut TokenStream2) { fn to_tokens(&self, stream: &mut TokenStream2) {
let ident = match self { let ident = format_ident!("to");
ResourceType::Async => "to",
ResourceType::Sync => "to",
};
let ident = Ident::new(ident, Span::call_site());
stream.append(ident); stream.append(ident);
} }
} }
@ -52,8 +48,7 @@ impl GuardType {
impl ToTokens for GuardType { impl ToTokens for GuardType {
fn to_tokens(&self, stream: &mut TokenStream2) { fn to_tokens(&self, stream: &mut TokenStream2) {
let ident = self.as_str(); let ident = Ident::new(self.as_str(), Span::call_site());
let ident = Ident::new(ident, Span::call_site());
stream.append(ident); stream.append(ident);
} }
} }
@ -93,12 +88,12 @@ impl Args {
} else { } else {
return Err(syn::Error::new_spanned( return Err(syn::Error::new_spanned(
nv.path, nv.path,
"Unknown attribute key is specified. Allowed: guard", "Unknown attribute key is specified. Allowed: guard.",
)); ));
} }
} }
arg => { 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, guard,
}) })
} }
}
pub fn generate(&self) -> TokenStream { impl ToTokens for Route {
let name = &self.name; 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 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! { let stream = quote! {
#[allow(non_camel_case_types, missing_docs)] #[allow(non_camel_case_types, missing_docs)]
pub struct #name; pub struct #name;
@ -200,13 +198,14 @@ impl Route {
let __resource = actix_web::Resource::new(#path) let __resource = actix_web::Resource::new(#path)
.name(#resource_name) .name(#resource_name)
.guard(actix_web::guard::#guard()) .guard(actix_web::guard::#guard())
#(.guard(actix_web::guard::fn_guard(#extra_guards)))* #(.guard(actix_web::guard::fn_guard(#guards)))*
.#resource_type(#name); .#resource_type(#name);
actix_web::dev::HttpServiceFactory::register(__resource, __config) actix_web::dev::HttpServiceFactory::register(__resource, __config)
} }
} }
}; };
stream.into()
output.extend(stream);
} }
} }