1
0
Fork 0
mirror of https://gitlab.com/msrd0/gotham-restful.git synced 2025-02-22 20:52:27 +00:00

get rid of mod's in error messages

This commit is contained in:
Dominic 2020-11-23 01:22:03 +01:00
parent f9c2009023
commit 4fd5464e44
Signed by: msrd0
GPG key ID: DCC8C247452E98F9
8 changed files with 91 additions and 127 deletions

View file

@ -4,7 +4,7 @@ use proc_macro2::{Ident, Span, TokenStream};
use quote::{format_ident, quote};
use std::str::FromStr;
use syn::{
spanned::Spanned, Attribute, AttributeArgs, Error, FnArg, ItemFn, Lit, LitBool, Meta, NestedMeta, PatType, Result,
spanned::Spanned, Attribute, AttributeArgs, Error, FnArg, ItemFn, Lit, LitBool, Meta, NestedMeta, PatType, Path, Result,
ReturnType, Type
};
@ -82,20 +82,12 @@ impl Method {
format_ident!("{}", name)
}
pub fn mod_ident(&self, resource: &str) -> Ident {
format_ident!(
"_gotham_restful_resource_{}_method_{}",
resource.to_snake_case(),
self.fn_ident()
)
}
pub fn handler_struct_ident(&self, resource: &str) -> Ident {
format_ident!("{}{}Handler", resource.to_camel_case(), self.trait_ident())
}
pub fn setup_ident(&self, resource: &str) -> Ident {
format_ident!("{}_{}_setup_impl", resource.to_snake_case(), self.fn_ident())
format_ident!("_gotham_restful_{}_{}_setup_impl", resource.to_snake_case(), self.fn_ident())
}
}
@ -249,33 +241,16 @@ fn expand_wants_auth(attrs: &[NestedMeta], default: bool) -> TokenStream {
}
#[allow(clippy::comparison_chain)]
pub fn expand_method(method: Method, mut attrs: AttributeArgs, fun: ItemFn) -> Result<TokenStream> {
fn setup_body(
method: &Method,
fun: &ItemFn,
attrs: &[NestedMeta],
resource_name: &str,
resource_path: &Path
) -> Result<TokenStream> {
let krate = super::krate();
// parse attributes
if attrs.len() < 1 {
return Err(Error::new(
Span::call_site(),
"Missing Resource struct. Example: #[read_all(MyResource)]"
));
}
let resource_path = match attrs.remove(0) {
NestedMeta::Meta(Meta::Path(path)) => path,
p => {
return Err(Error::new(
p.span(),
"Expected name of the Resource struct this method belongs to"
))
},
};
let resource_name = resource_path
.segments
.last()
.map(|s| s.ident.to_string())
.ok_or_else(|| Error::new(resource_path.span(), "Resource name must not be empty"))?;
let fun_ident = &fun.sig.ident;
let fun_vis = &fun.vis;
let fun_is_async = fun.sig.asyncness.is_some();
if let Some(unsafety) = fun.sig.unsafety {
@ -284,9 +259,7 @@ pub fn expand_method(method: Method, mut attrs: AttributeArgs, fun: ItemFn) -> R
let trait_ident = method.trait_ident();
let method_ident = method.fn_ident();
let mod_ident = method.mod_ident(&resource_name);
let handler_ident = method.handler_struct_ident(&resource_name);
let setup_ident = method.setup_ident(&resource_name);
let handler_ident = method.handler_struct_ident(resource_name);
let (ret, is_no_content) = match &fun.sig.output {
ReturnType::Default => (quote!(#krate::NoContent), true),
@ -410,52 +383,84 @@ pub fn expand_method(method: Method, mut attrs: AttributeArgs, fun: ItemFn) -> R
}
// attribute generated code
let operation_id = expand_operation_id(&attrs);
let wants_auth = expand_wants_auth(&attrs, args.iter().any(|arg| (*arg).ty.is_auth_status()));
let operation_id = expand_operation_id(attrs);
let wants_auth = expand_wants_auth(attrs, args.iter().any(|arg| (*arg).ty.is_auth_status()));
// put everything together
let mut dummy = format_ident!("_IMPL_RESOURCEMETHOD_FOR_{}", fun_ident);
dummy.set_span(Span::call_site());
Ok(quote! {
struct #handler_ident;
impl #krate::ResourceMethod for #handler_ident {
type Res = #ret;
#operation_id
#wants_auth
}
impl #krate::#trait_ident for #handler_ident
where #where_clause
{
#(#generics)*
fn #method_ident(#(#args_def),*) -> std::pin::Pin<Box<dyn std::future::Future<Output = (#krate::State, #ret)> + Send>> {
#[allow(unused_imports)]
use #krate::{export::FutureExt, FromState};
#state_block
async move {
let #res_ident = { #block };
(#state_ident, #res_ident)
}.boxed()
}
}
route.#method_ident::<#handler_ident>();
})
}
pub fn expand_method(method: Method, mut attrs: AttributeArgs, fun: ItemFn) -> Result<TokenStream> {
let krate = super::krate();
// parse attributes
if attrs.len() < 1 {
return Err(Error::new(
Span::call_site(),
"Missing Resource struct. Example: #[read_all(MyResource)]"
));
}
let resource_path = match attrs.remove(0) {
NestedMeta::Meta(Meta::Path(path)) => path,
p => {
return Err(Error::new(
p.span(),
"Expected name of the Resource struct this method belongs to"
))
},
};
let resource_name = resource_path
.segments
.last()
.map(|s| s.ident.to_string())
.ok_or_else(|| Error::new(resource_path.span(), "Resource name must not be empty"))?;
let fun_vis = &fun.vis;
let setup_ident = method.setup_ident(&resource_name);
let setup_body = match setup_body(&method, &fun, &attrs, &resource_name, &resource_path) {
Ok(body) => body,
Err(err) => err.to_compile_error()
};
Ok(quote! {
#fun
#fun_vis mod #mod_ident
{
use super::*;
struct #handler_ident;
impl #krate::ResourceMethod for #handler_ident
{
type Res = #ret;
#operation_id
#wants_auth
}
impl #krate::#trait_ident for #handler_ident
where #where_clause
{
#(#generics)*
fn #method_ident(#(#args_def),*) -> std::pin::Pin<Box<dyn std::future::Future<Output = (#krate::State, #ret)> + Send>>
{
#[allow(unused_imports)]
use #krate::{export::FutureExt, FromState};
#state_block
async move {
let #res_ident = { #block };
(#state_ident, #res_ident)
}.boxed()
}
}
#[deny(dead_code)]
pub fn #setup_ident<D : #krate::DrawResourceRoutes>(route : &mut D)
{
route.#method_ident::<#handler_ident>();
}
#[deny(dead_code)]
#[doc(hidden)]
/// `gotham_restful` implementation detail.
#fun_vis fn #setup_ident<D : #krate::DrawResourceRoutes>(route : &mut D) {
#setup_body
}
})
}

View file

@ -38,9 +38,8 @@ pub fn expand_resource(input: DeriveInput) -> Result<TokenStream> {
.flat_map(|list| match list {
Ok(iter) => Box::new(iter.map(|method| {
let method = Method::from_str(&method.to_string()).map_err(|err| Error::new(method.span(), err))?;
let mod_ident = method.mod_ident(&name);
let ident = method.setup_ident(&name);
Ok(quote!(#mod_ident::#ident(&mut route);))
Ok(quote!(#ident(&mut route);))
})) as Box<dyn Iterator<Item = Result<TokenStream>>>,
Err(err) => Box::new(iter::once(Err(err)))
})

View file

@ -3,19 +3,3 @@ error: async fn must not take &State as an argument as State is not Sync, consid
|
9 | async fn read_all(state : &State)
| ^^^^^
error[E0433]: failed to resolve: use of undeclared crate or module `_gotham_restful_resource_foo_resource_method_read_all`
--> $DIR/method_async_state.rs:4:10
|
4 | #[derive(Resource)]
| ^^^^^^^^ use of undeclared crate or module `_gotham_restful_resource_foo_resource_method_read_all`
|
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
warning: unused import: `gotham_restful::State`
--> $DIR/method_async_state.rs:2:5
|
2 | use gotham_restful::State;
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default

View file

@ -6,10 +6,10 @@ error: Missing Resource struct. Example: #[read_all(MyResource)]
|
= note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0433]: failed to resolve: use of undeclared crate or module `_gotham_restful_resource_foo_resource_method_read_all`
error[E0425]: cannot find function `_gotham_restful_foo_resource_read_all_setup_impl` in this scope
--> $DIR/method_no_resource.rs:3:10
|
3 | #[derive(Resource)]
| ^^^^^^^^ use of undeclared crate or module `_gotham_restful_resource_foo_resource_method_read_all`
| ^^^^^^^^ not found in this scope
|
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)

View file

@ -4,10 +4,10 @@ error: Didn't expect self parameter
8 | fn read_all(self)
| ^^^^
error[E0433]: failed to resolve: use of undeclared crate or module `_gotham_restful_resource_foo_resource_method_read_all`
--> $DIR/method_self.rs:3:10
error: `self` parameter is only allowed in associated functions
--> $DIR/method_self.rs:8:13
|
3 | #[derive(Resource)]
| ^^^^^^^^ use of undeclared crate or module `_gotham_restful_resource_foo_resource_method_read_all`
8 | fn read_all(self)
| ^^^^ not semantically valid as function parameter
|
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
= note: associated functions are those in `impl` or `trait` definitions

View file

@ -3,11 +3,3 @@ error: Too few arguments
|
8 | fn read()
| ^^^^
error[E0433]: failed to resolve: use of undeclared crate or module `_gotham_restful_resource_foo_resource_method_read`
--> $DIR/method_too_few_args.rs:3:10
|
3 | #[derive(Resource)]
| ^^^^^^^^ use of undeclared crate or module `_gotham_restful_resource_foo_resource_method_read`
|
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)

View file

@ -3,11 +3,3 @@ error: Too many arguments
|
8 | fn read_all(_id : u64)
| ^^^
error[E0433]: failed to resolve: use of undeclared crate or module `_gotham_restful_resource_foo_resource_method_read_all`
--> $DIR/method_too_many_args.rs:3:10
|
3 | #[derive(Resource)]
| ^^^^^^^^ use of undeclared crate or module `_gotham_restful_resource_foo_resource_method_read_all`
|
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)

View file

@ -3,11 +3,3 @@ error: Resource methods must not be unsafe
|
8 | unsafe fn read_all()
| ^^^^^^
error[E0433]: failed to resolve: use of undeclared crate or module `_gotham_restful_resource_foo_resource_method_read_all`
--> $DIR/method_unsafe.rs:3:10
|
3 | #[derive(Resource)]
| ^^^^^^^^ use of undeclared crate or module `_gotham_restful_resource_foo_resource_method_read_all`
|
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)