route handler macro accepts idents

This commit is contained in:
realaravinth 2021-05-13 19:22:44 +05:30
parent f277b128b6
commit 0b61bd6b0b
No known key found for this signature in database
GPG Key ID: AD9F0F08E855ED88
2 changed files with 49 additions and 4 deletions

View File

@ -77,16 +77,23 @@ impl TryFrom<&syn::LitStr> for MethodType {
}
struct Args {
path: syn::LitStr,
//path: Option<syn::LitStr>,
path: Box<dyn PathMarker>,
// i_path: Option<syn::Ident>,
resource_name: Option<syn::LitStr>,
guards: Vec<Ident>,
wrappers: Vec<syn::Type>,
methods: HashSet<MethodType>,
}
trait PathMarker: quote::ToTokens {}
impl PathMarker for syn::Ident {}
impl PathMarker for syn::LitStr {}
impl Args {
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 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);
}
}

View File

@ -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();