mirror of https://github.com/fafhrd91/actix-web
route handler macro accepts idents
This commit is contained in:
parent
f277b128b6
commit
0b61bd6b0b
|
@ -77,16 +77,23 @@ impl TryFrom<&syn::LitStr> for MethodType {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Args {
|
struct Args {
|
||||||
path: syn::LitStr,
|
//path: Option<syn::LitStr>,
|
||||||
|
path: Box<dyn PathMarker>,
|
||||||
|
// i_path: Option<syn::Ident>,
|
||||||
resource_name: Option<syn::LitStr>,
|
resource_name: Option<syn::LitStr>,
|
||||||
guards: Vec<Ident>,
|
guards: Vec<Ident>,
|
||||||
wrappers: Vec<syn::Type>,
|
wrappers: Vec<syn::Type>,
|
||||||
methods: HashSet<MethodType>,
|
methods: HashSet<MethodType>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trait PathMarker: quote::ToTokens {}
|
||||||
|
|
||||||
|
impl PathMarker for syn::Ident {}
|
||||||
|
impl PathMarker for syn::LitStr {}
|
||||||
|
|
||||||
impl Args {
|
impl Args {
|
||||||
fn new(args: AttributeArgs, method: Option<MethodType>) -> syn::Result<Self> {
|
fn new(args: AttributeArgs, method: Option<MethodType>) -> syn::Result<Self> {
|
||||||
let mut path = None;
|
let mut path: Option<Box<dyn PathMarker>> = None;
|
||||||
let mut resource_name = None;
|
let mut resource_name = None;
|
||||||
let mut guards = Vec::new();
|
let mut guards = Vec::new();
|
||||||
let mut wrappers = Vec::new();
|
let mut wrappers = Vec::new();
|
||||||
|
@ -101,8 +108,9 @@ impl Args {
|
||||||
match arg {
|
match arg {
|
||||||
NestedMeta::Lit(syn::Lit::Str(lit)) => match path {
|
NestedMeta::Lit(syn::Lit::Str(lit)) => match path {
|
||||||
None => {
|
None => {
|
||||||
path = Some(lit);
|
path = Some(Box::new(lit));
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
return Err(syn::Error::new_spanned(
|
return Err(syn::Error::new_spanned(
|
||||||
lit,
|
lit,
|
||||||
|
@ -120,6 +128,31 @@ impl Args {
|
||||||
"Attribute name expects literal string!",
|
"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") {
|
} else if nv.path.is_ident("guard") {
|
||||||
if let syn::Lit::Str(lit) = nv.lit {
|
if let syn::Lit::Str(lit) = nv.lit {
|
||||||
guards.push(Ident::new(&lit.value(), Span::call_site()));
|
guards.push(Ident::new(&lit.value(), Span::call_site()));
|
||||||
|
@ -173,6 +206,7 @@ impl Args {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Args {
|
Ok(Args {
|
||||||
path: path.unwrap(),
|
path: path.unwrap(),
|
||||||
resource_name,
|
resource_name,
|
||||||
|
@ -318,6 +352,8 @@ impl ToTokens for Route {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let path = path.as_ref();
|
||||||
|
|
||||||
let stream = quote! {
|
let stream = quote! {
|
||||||
#(#doc_attributes)*
|
#(#doc_attributes)*
|
||||||
#[allow(non_camel_case_types, missing_docs)]
|
#[allow(non_camel_case_types, missing_docs)]
|
||||||
|
@ -337,7 +373,6 @@ impl ToTokens for Route {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
output.extend(stream);
|
output.extend(stream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,12 @@ async fn config() -> impl Responder {
|
||||||
HttpResponse::Ok()
|
HttpResponse::Ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PATH: &str = "/path";
|
||||||
|
#[get(path = "PATH")]
|
||||||
|
async fn path() -> impl Responder {
|
||||||
|
HttpResponse::Ok()
|
||||||
|
}
|
||||||
|
|
||||||
#[get("/test")]
|
#[get("/test")]
|
||||||
async fn test_handler() -> impl Responder {
|
async fn test_handler() -> impl Responder {
|
||||||
HttpResponse::Ok()
|
HttpResponse::Ok()
|
||||||
|
@ -158,7 +164,11 @@ async fn test_params() {
|
||||||
.service(get_param_test)
|
.service(get_param_test)
|
||||||
.service(put_param_test)
|
.service(put_param_test)
|
||||||
.service(delete_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 request = srv.request(http::Method::GET, srv.url("/test/it"));
|
||||||
let response = request.send().await.unwrap();
|
let response = request.send().await.unwrap();
|
||||||
|
|
Loading…
Reference in New Issue