diff --git a/actix-web-codegen/src/route.rs b/actix-web-codegen/src/route.rs index ac0b7cea1..fc1260f39 100644 --- a/actix-web-codegen/src/route.rs +++ b/actix-web-codegen/src/route.rs @@ -77,16 +77,23 @@ impl TryFrom<&syn::LitStr> for MethodType { } struct Args { - path: syn::LitStr, + //path: Option, + path: Box, + // i_path: Option, resource_name: Option, guards: Vec, wrappers: Vec, methods: HashSet, } +trait PathMarker: quote::ToTokens {} + +impl PathMarker for syn::Ident {} +impl PathMarker for syn::LitStr {} + impl Args { fn new(args: AttributeArgs, method: Option) -> syn::Result { - let mut path = None; + let mut path: Option> = None; let mut resource_name = None; let mut guards = Vec::new(); let mut wrappers = Vec::new(); @@ -101,8 +108,9 @@ impl Args { match arg { NestedMeta::Lit(syn::Lit::Str(lit)) => match path { None => { - path = Some(lit); + path = Some(Box::new(lit)); } + _ => { return Err(syn::Error::new_spanned( lit, @@ -120,6 +128,31 @@ impl Args { "Attribute name expects literal string!", )); } + } else if nv.path.is_ident("path") { + if let syn::Lit::Str(lit) = nv.lit { + // path = Some(syn::LitStr::new( + // &Ident::new(&lit.value(), Span::call_site()).to_string(), + // Span::call_site(), + // )); + + match path { + None => { + let x = Ident::new(&lit.value(), Span::call_site()); + path = Some(Box::new(x)); + } + _ => { + return Err(syn::Error::new_spanned( + lit, + "Multiple paths specified! Should be only one!", + )); + } + } + } else { + return Err(syn::Error::new_spanned( + nv.lit, + "Attribute path expects literal string!", + )); + } } else if nv.path.is_ident("guard") { if let syn::Lit::Str(lit) = nv.lit { guards.push(Ident::new(&lit.value(), Span::call_site())); @@ -173,6 +206,7 @@ impl Args { } } } + Ok(Args { path: path.unwrap(), resource_name, @@ -318,6 +352,8 @@ impl ToTokens for Route { } }; + let path = path.as_ref(); + let stream = quote! { #(#doc_attributes)* #[allow(non_camel_case_types, missing_docs)] @@ -337,7 +373,6 @@ impl ToTokens for Route { } } }; - output.extend(stream); } } diff --git a/actix-web-codegen/tests/test_macro.rs b/actix-web-codegen/tests/test_macro.rs index 6b08c409c..d276dcf7e 100644 --- a/actix-web-codegen/tests/test_macro.rs +++ b/actix-web-codegen/tests/test_macro.rs @@ -19,6 +19,12 @@ async fn config() -> impl Responder { HttpResponse::Ok() } +const PATH: &str = "/path"; +#[get(path = "PATH")] +async fn path() -> impl Responder { + HttpResponse::Ok() +} + #[get("/test")] async fn test_handler() -> impl Responder { HttpResponse::Ok() @@ -158,7 +164,11 @@ async fn test_params() { .service(get_param_test) .service(put_param_test) .service(delete_param_test) + .service(path) }); + let request = srv.request(http::Method::GET, srv.url(PATH)); + let response = request.send().await.unwrap(); + assert_eq!(response.status(), http::StatusCode::OK); let request = srv.request(http::Method::GET, srv.url("/test/it")); let response = request.send().await.unwrap();