From 928b8d8a72c5a31bf037b85eb2b0d139aaf68e91 Mon Sep 17 00:00:00 2001 From: Arniu Date: Tue, 22 Sep 2020 12:15:37 +0800 Subject: [PATCH] rename to `MethodType` --- actix-web-codegen/src/lib.rs | 18 +++--- actix-web-codegen/src/route.rs | 104 +++++++++++++++++---------------- 2 files changed, 63 insertions(+), 59 deletions(-) diff --git a/actix-web-codegen/src/lib.rs b/actix-web-codegen/src/lib.rs index 9f2d1d828..39cbf15b4 100644 --- a/actix-web-codegen/src/lib.rs +++ b/actix-web-codegen/src/lib.rs @@ -58,7 +58,7 @@ use proc_macro::TokenStream; /// - `wrap = "Middleware"` - Registers a resource middleware. #[proc_macro_attribute] pub fn get(args: TokenStream, input: TokenStream) -> TokenStream { - route::with_method(Some(route::Method::Get), args, input) + route::with_method(Some(route::MethodType::Get), args, input) } /// Creates route handler with `POST` method guard. @@ -68,7 +68,7 @@ pub fn get(args: TokenStream, input: TokenStream) -> TokenStream { /// Attributes are the same as in [get](attr.get.html) #[proc_macro_attribute] pub fn post(args: TokenStream, input: TokenStream) -> TokenStream { - route::with_method(Some(route::Method::Post), args, input) + route::with_method(Some(route::MethodType::Post), args, input) } /// Creates route handler with `PUT` method guard. @@ -78,7 +78,7 @@ pub fn post(args: TokenStream, input: TokenStream) -> TokenStream { /// Attributes are the same as in [get](attr.get.html) #[proc_macro_attribute] pub fn put(args: TokenStream, input: TokenStream) -> TokenStream { - route::with_method(Some(route::Method::Put), args, input) + route::with_method(Some(route::MethodType::Put), args, input) } /// Creates route handler with `DELETE` method guard. @@ -88,7 +88,7 @@ pub fn put(args: TokenStream, input: TokenStream) -> TokenStream { /// Attributes are the same as in [get](attr.get.html). #[proc_macro_attribute] pub fn delete(args: TokenStream, input: TokenStream) -> TokenStream { - route::with_method(Some(route::Method::Delete), args, input) + route::with_method(Some(route::MethodType::Delete), args, input) } /// Creates route handler with `HEAD` method guard. @@ -98,7 +98,7 @@ pub fn delete(args: TokenStream, input: TokenStream) -> TokenStream { /// Attributes are the same as in [get](attr.get.html). #[proc_macro_attribute] pub fn head(args: TokenStream, input: TokenStream) -> TokenStream { - route::with_method(Some(route::Method::Head), args, input) + route::with_method(Some(route::MethodType::Head), args, input) } /// Creates route handler with `CONNECT` method guard. @@ -108,7 +108,7 @@ pub fn head(args: TokenStream, input: TokenStream) -> TokenStream { /// Attributes are the same as in [get](attr.get.html). #[proc_macro_attribute] pub fn connect(args: TokenStream, input: TokenStream) -> TokenStream { - route::with_method(Some(route::Method::Connect), args, input) + route::with_method(Some(route::MethodType::Connect), args, input) } /// Creates route handler with `OPTIONS` method guard. @@ -118,7 +118,7 @@ pub fn connect(args: TokenStream, input: TokenStream) -> TokenStream { /// Attributes are the same as in [get](attr.get.html). #[proc_macro_attribute] pub fn options(args: TokenStream, input: TokenStream) -> TokenStream { - route::with_method(Some(route::Method::Options), args, input) + route::with_method(Some(route::MethodType::Options), args, input) } /// Creates route handler with `TRACE` method guard. @@ -128,7 +128,7 @@ pub fn options(args: TokenStream, input: TokenStream) -> TokenStream { /// Attributes are the same as in [get](attr.get.html). #[proc_macro_attribute] pub fn trace(args: TokenStream, input: TokenStream) -> TokenStream { - route::with_method(Some(route::Method::Trace), args, input) + route::with_method(Some(route::MethodType::Trace), args, input) } /// Creates route handler with `PATCH` method guard. @@ -138,7 +138,7 @@ pub fn trace(args: TokenStream, input: TokenStream) -> TokenStream { /// Attributes are the same as in [get](attr.get.html). #[proc_macro_attribute] pub fn patch(args: TokenStream, input: TokenStream) -> TokenStream { - route::with_method(Some(route::Method::Patch), args, input) + route::with_method(Some(route::MethodType::Patch), args, input) } /// Creates resource handler, allowing multiple HTTP method guards. diff --git a/actix-web-codegen/src/route.rs b/actix-web-codegen/src/route.rs index 5f8914695..498b3dc20 100644 --- a/actix-web-codegen/src/route.rs +++ b/actix-web-codegen/src/route.rs @@ -20,61 +20,61 @@ impl ToTokens for ResourceType { } } -#[derive(Debug, PartialEq, Eq, Hash)] -pub enum Method { - Get, - Post, - Put, - Delete, - Head, - Connect, - Options, - Trace, - Patch, -} - -impl Method { - fn as_str(&self) -> &'static str { - match self { - Method::Get => "Get", - Method::Post => "Post", - Method::Put => "Put", - Method::Delete => "Delete", - Method::Head => "Head", - Method::Connect => "Connect", - Method::Options => "Options", - Method::Trace => "Trace", - Method::Patch => "Patch", +macro_rules! method_type { + ( + $( + ($variant:ident, $upper:ident); + )+ + ) => { + #[derive(Debug, PartialEq, Eq, Hash)] + pub enum MethodType { + $( + $variant, + )+ } - } + + impl MethodType { + fn as_str(&self) -> &'static str { + match self { + $(Self::$variant => stringify!($variant),)+ + } + } + + fn parse(method: &str) -> Result { + match method { + $(stringify!($upper) => Ok(Self::$variant),)+ + _ => Err(format!("Unexpected HTTP method: `{}`", method)), + } + } + } + }; } -impl ToTokens for Method { +method_type! { + (Get, GET); + (Post, POST); + (Put, PUT); + (Delete, DELETE); + (Head, HEAD); + (Connect, CONNECT); + (Options, OPTIONS); + (Trace, TRACE); + (Patch, PATCH); +} + +impl ToTokens for MethodType { fn to_tokens(&self, stream: &mut TokenStream2) { let ident = Ident::new(self.as_str(), Span::call_site()); stream.append(ident); } } -impl TryFrom<&syn::LitStr> for Method { +impl TryFrom<&syn::LitStr> for MethodType { type Error = syn::Error; fn try_from(value: &syn::LitStr) -> Result { - match value.value().as_str() { - "CONNECT" => Ok(Method::Connect), - "DELETE" => Ok(Method::Delete), - "GET" => Ok(Method::Get), - "HEAD" => Ok(Method::Head), - "OPTIONS" => Ok(Method::Options), - "PATCH" => Ok(Method::Patch), - "POST" => Ok(Method::Post), - "PUT" => Ok(Method::Put), - "TRACE" => Ok(Method::Trace), - _ => Err(syn::Error::new_spanned( - value, - &format!("Unexpected HTTP Method: `{}`", value.value()), - )), - } + Self::parse(value.value().as_str()) + .map_err(|message| syn::Error::new_spanned(value, message)) } } @@ -82,14 +82,19 @@ struct Args { path: syn::LitStr, guards: Vec, wrappers: Vec, - methods: HashSet, + methods: HashSet, } impl Args { - fn new(args: AttributeArgs, mut methods: HashSet) -> syn::Result { + fn new(args: AttributeArgs, method: Option) -> syn::Result { let mut path = None; let mut guards = Vec::new(); let mut wrappers = Vec::new(); + let mut methods = HashSet::new(); + if let Some(method) = method { + methods.insert(method); + } + for arg in args { match arg { NestedMeta::Lit(syn::Lit::Str(lit)) => match path { @@ -124,7 +129,7 @@ impl Args { } } else if nv.path.is_ident("method") { if let syn::Lit::Str(ref lit) = nv.lit { - let method = Method::try_from(lit)?; + let method = MethodType::try_from(lit)?; if !methods.insert(method) { return Err(syn::Error::new_spanned( &nv.lit, @@ -194,7 +199,7 @@ impl Route { pub fn new( args: AttributeArgs, input: TokenStream, - method: Option, + method: Option, ) -> syn::Result { if args.is_empty() { return Err(syn::Error::new( @@ -211,8 +216,7 @@ impl Route { let ast: syn::ItemFn = syn::parse(input)?; let name = ast.sig.ident.clone(); - let methods = method.into_iter().collect(); - let args = Args::new(args, methods)?; + let args = Args::new(args, method)?; if args.methods.is_empty() { return Err(syn::Error::new( Span::call_site(), @@ -301,7 +305,7 @@ impl ToTokens for Route { } pub(crate) fn with_method( - method: Option, + method: Option, args: TokenStream, input: TokenStream, ) -> TokenStream {