mirror of
https://gitlab.com/msrd0/gotham-restful.git
synced 2025-02-23 04:52:28 +00:00
improve ui on invalid types for endpoints
This commit is contained in:
parent
90fc17e57d
commit
30edd349ed
9 changed files with 169 additions and 5 deletions
|
@ -2,7 +2,7 @@ use crate::util::{CollectToResult, ExpectLit, PathEndsWith};
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use paste::paste;
|
use paste::paste;
|
||||||
use proc_macro2::{Ident, Span, TokenStream};
|
use proc_macro2::{Ident, Span, TokenStream};
|
||||||
use quote::{format_ident, quote, ToTokens};
|
use quote::{format_ident, quote, quote_spanned, ToTokens};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use syn::{
|
use syn::{
|
||||||
|
@ -405,6 +405,7 @@ fn expand_endpoint_type(mut ty: EndpointType, attrs: AttributeArgs, fun: &ItemFn
|
||||||
ReturnType::Default => (quote!(::gotham_restful::NoContent), true),
|
ReturnType::Default => (quote!(::gotham_restful::NoContent), true),
|
||||||
ReturnType::Type(_, ty) => (quote!(#ty), false)
|
ReturnType::Type(_, ty) => (quote!(#ty), false)
|
||||||
};
|
};
|
||||||
|
let output_typedef = quote_spanned!(output_ty.span() => type Output = #output_ty;);
|
||||||
|
|
||||||
let arg_tys = args.iter().filter(|arg| arg.ty.is_method_arg()).collect::<Vec<_>>();
|
let arg_tys = args.iter().filter(|arg| arg.ty.is_method_arg()).collect::<Vec<_>>();
|
||||||
let mut arg_ty_idx = 0;
|
let mut arg_ty_idx = 0;
|
||||||
|
@ -434,10 +435,13 @@ fn expand_endpoint_type(mut ty: EndpointType, attrs: AttributeArgs, fun: &ItemFn
|
||||||
})?;
|
})?;
|
||||||
let has_placeholders = ty.has_placeholders();
|
let has_placeholders = ty.has_placeholders();
|
||||||
let placeholder_ty = ty.placeholders_ty(next_arg_ty(!has_placeholders.value)?);
|
let placeholder_ty = ty.placeholders_ty(next_arg_ty(!has_placeholders.value)?);
|
||||||
|
let placeholder_typedef = quote_spanned!(placeholder_ty.span() => type Placeholders = #placeholder_ty;);
|
||||||
let needs_params = ty.needs_params();
|
let needs_params = ty.needs_params();
|
||||||
let params_ty = ty.params_ty(next_arg_ty(!needs_params.value)?);
|
let params_ty = ty.params_ty(next_arg_ty(!needs_params.value)?);
|
||||||
|
let params_typedef = quote_spanned!(params_ty.span() => type Params = #params_ty;);
|
||||||
let needs_body = ty.needs_body();
|
let needs_body = ty.needs_body();
|
||||||
let body_ty = ty.body_ty(next_arg_ty(!needs_body.value)?);
|
let body_ty = ty.body_ty(next_arg_ty(!needs_body.value)?);
|
||||||
|
let body_typedef = quote_spanned!(body_ty.span() => type Body = #body_ty;);
|
||||||
|
|
||||||
if arg_ty_idx < arg_tys.len() {
|
if arg_ty_idx < arg_tys.len() {
|
||||||
return Err(Error::new(fun_ident.span(), "Too many arguments"));
|
return Err(Error::new(fun_ident.span(), "Too many arguments"));
|
||||||
|
@ -537,22 +541,22 @@ fn expand_endpoint_type(mut ty: EndpointType, attrs: AttributeArgs, fun: &ItemFn
|
||||||
{ #uri }.into()
|
{ #uri }.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
type Output = #output_ty;
|
#output_typedef
|
||||||
|
|
||||||
fn has_placeholders() -> bool {
|
fn has_placeholders() -> bool {
|
||||||
#has_placeholders
|
#has_placeholders
|
||||||
}
|
}
|
||||||
type Placeholders = #placeholder_ty;
|
#placeholder_typedef
|
||||||
|
|
||||||
fn needs_params() -> bool {
|
fn needs_params() -> bool {
|
||||||
#needs_params
|
#needs_params
|
||||||
}
|
}
|
||||||
type Params = #params_ty;
|
#params_typedef
|
||||||
|
|
||||||
fn needs_body() -> bool {
|
fn needs_body() -> bool {
|
||||||
#needs_body
|
#needs_body
|
||||||
}
|
}
|
||||||
type Body = #body_ty;
|
#body_typedef
|
||||||
|
|
||||||
fn handle<'a>(
|
fn handle<'a>(
|
||||||
state: &'a mut ::gotham_restful::gotham::state::State,
|
state: &'a mut ::gotham_restful::gotham::state::State,
|
||||||
|
|
19
tests/ui/endpoint/invalid_body_ty.rs
Normal file
19
tests/ui/endpoint/invalid_body_ty.rs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#[macro_use]
|
||||||
|
extern crate gotham_restful;
|
||||||
|
use gotham_restful::gotham::hyper::Method;
|
||||||
|
|
||||||
|
#[derive(Resource)]
|
||||||
|
#[resource(endpoint)]
|
||||||
|
struct FooResource;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct FooBody {
|
||||||
|
foo: String
|
||||||
|
}
|
||||||
|
|
||||||
|
#[endpoint(method = "Method::GET", uri = "", body = true)]
|
||||||
|
fn endpoint(_: FooBody) {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
13
tests/ui/endpoint/invalid_body_ty.stderr
Normal file
13
tests/ui/endpoint/invalid_body_ty.stderr
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
error[E0277]: the trait bound `for<'de> FooBody: serde::de::Deserialize<'de>` is not satisfied
|
||||||
|
--> $DIR/invalid_body_ty.rs:15:16
|
||||||
|
|
|
||||||
|
15 | fn endpoint(_: FooBody) {
|
||||||
|
| ^^^^^^^ the trait `for<'de> serde::de::Deserialize<'de>` is not implemented for `FooBody`
|
||||||
|
|
|
||||||
|
::: $WORKSPACE/src/endpoint.rs
|
||||||
|
|
|
||||||
|
| type Body: RequestBody + Send;
|
||||||
|
| ----------- required by this bound in `gotham_restful::Endpoint::Body`
|
||||||
|
|
|
||||||
|
= note: required because of the requirements on the impl of `serde::de::DeserializeOwned` for `FooBody`
|
||||||
|
= note: required because of the requirements on the impl of `RequestBody` for `FooBody`
|
19
tests/ui/endpoint/invalid_params_ty.rs
Normal file
19
tests/ui/endpoint/invalid_params_ty.rs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#[macro_use]
|
||||||
|
extern crate gotham_restful;
|
||||||
|
use gotham_restful::gotham::hyper::Method;
|
||||||
|
|
||||||
|
#[derive(Resource)]
|
||||||
|
#[resource(endpoint)]
|
||||||
|
struct FooResource;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct FooParams {
|
||||||
|
foo: String
|
||||||
|
}
|
||||||
|
|
||||||
|
#[endpoint(method = "Method::GET", uri = "", params = true)]
|
||||||
|
fn endpoint(_: FooParams) {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
32
tests/ui/endpoint/invalid_params_ty.stderr
Normal file
32
tests/ui/endpoint/invalid_params_ty.stderr
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
error[E0277]: the trait bound `for<'de> FooParams: serde::de::Deserialize<'de>` is not satisfied
|
||||||
|
--> $DIR/invalid_params_ty.rs:15:16
|
||||||
|
|
|
||||||
|
15 | fn endpoint(_: FooParams) {
|
||||||
|
| ^^^^^^^^^ the trait `for<'de> serde::de::Deserialize<'de>` is not implemented for `FooParams`
|
||||||
|
|
|
||||||
|
::: $WORKSPACE/src/endpoint.rs
|
||||||
|
|
|
||||||
|
| type Params: QueryStringExtractor<Body> + Sync;
|
||||||
|
| -------------------------- required by this bound in `gotham_restful::Endpoint::Params`
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `FooParams: StateData` is not satisfied
|
||||||
|
--> $DIR/invalid_params_ty.rs:15:16
|
||||||
|
|
|
||||||
|
15 | fn endpoint(_: FooParams) {
|
||||||
|
| ^^^^^^^^^ the trait `StateData` is not implemented for `FooParams`
|
||||||
|
|
|
||||||
|
::: $WORKSPACE/src/endpoint.rs
|
||||||
|
|
|
||||||
|
| type Params: QueryStringExtractor<Body> + Sync;
|
||||||
|
| -------------------------- required by this bound in `gotham_restful::Endpoint::Params`
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `FooParams: StaticResponseExtender` is not satisfied
|
||||||
|
--> $DIR/invalid_params_ty.rs:15:16
|
||||||
|
|
|
||||||
|
15 | fn endpoint(_: FooParams) {
|
||||||
|
| ^^^^^^^^^ the trait `StaticResponseExtender` is not implemented for `FooParams`
|
||||||
|
|
|
||||||
|
::: $WORKSPACE/src/endpoint.rs
|
||||||
|
|
|
||||||
|
| type Params: QueryStringExtractor<Body> + Sync;
|
||||||
|
| -------------------------- required by this bound in `gotham_restful::Endpoint::Params`
|
19
tests/ui/endpoint/invalid_placeholders_ty.rs
Normal file
19
tests/ui/endpoint/invalid_placeholders_ty.rs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#[macro_use]
|
||||||
|
extern crate gotham_restful;
|
||||||
|
use gotham_restful::gotham::hyper::Method;
|
||||||
|
|
||||||
|
#[derive(Resource)]
|
||||||
|
#[resource(endpoint)]
|
||||||
|
struct FooResource;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct FooPlaceholders {
|
||||||
|
foo: String
|
||||||
|
}
|
||||||
|
|
||||||
|
#[endpoint(method = "Method::GET", uri = ":foo")]
|
||||||
|
fn endpoint(_: FooPlaceholders) {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
32
tests/ui/endpoint/invalid_placeholders_ty.stderr
Normal file
32
tests/ui/endpoint/invalid_placeholders_ty.stderr
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
error[E0277]: the trait bound `for<'de> FooPlaceholders: serde::de::Deserialize<'de>` is not satisfied
|
||||||
|
--> $DIR/invalid_placeholders_ty.rs:15:16
|
||||||
|
|
|
||||||
|
15 | fn endpoint(_: FooPlaceholders) {
|
||||||
|
| ^^^^^^^^^^^^^^^ the trait `for<'de> serde::de::Deserialize<'de>` is not implemented for `FooPlaceholders`
|
||||||
|
|
|
||||||
|
::: $WORKSPACE/src/endpoint.rs
|
||||||
|
|
|
||||||
|
| type Placeholders: PathExtractor<Body> + Sync;
|
||||||
|
| ------------------- required by this bound in `gotham_restful::Endpoint::Placeholders`
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `FooPlaceholders: StateData` is not satisfied
|
||||||
|
--> $DIR/invalid_placeholders_ty.rs:15:16
|
||||||
|
|
|
||||||
|
15 | fn endpoint(_: FooPlaceholders) {
|
||||||
|
| ^^^^^^^^^^^^^^^ the trait `StateData` is not implemented for `FooPlaceholders`
|
||||||
|
|
|
||||||
|
::: $WORKSPACE/src/endpoint.rs
|
||||||
|
|
|
||||||
|
| type Placeholders: PathExtractor<Body> + Sync;
|
||||||
|
| ------------------- required by this bound in `gotham_restful::Endpoint::Placeholders`
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `FooPlaceholders: StaticResponseExtender` is not satisfied
|
||||||
|
--> $DIR/invalid_placeholders_ty.rs:15:16
|
||||||
|
|
|
||||||
|
15 | fn endpoint(_: FooPlaceholders) {
|
||||||
|
| ^^^^^^^^^^^^^^^ the trait `StaticResponseExtender` is not implemented for `FooPlaceholders`
|
||||||
|
|
|
||||||
|
::: $WORKSPACE/src/endpoint.rs
|
||||||
|
|
|
||||||
|
| type Placeholders: PathExtractor<Body> + Sync;
|
||||||
|
| ------------------- required by this bound in `gotham_restful::Endpoint::Placeholders`
|
16
tests/ui/endpoint/invalid_return_type.rs
Normal file
16
tests/ui/endpoint/invalid_return_type.rs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
#[macro_use]
|
||||||
|
extern crate gotham_restful;
|
||||||
|
use gotham_restful::gotham::hyper::Method;
|
||||||
|
|
||||||
|
#[derive(Resource)]
|
||||||
|
#[resource(endpoint)]
|
||||||
|
struct FooResource;
|
||||||
|
|
||||||
|
struct FooResponse;
|
||||||
|
|
||||||
|
#[endpoint(method = "Method::GET", uri = "")]
|
||||||
|
fn endpoint() -> FooResponse {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
10
tests/ui/endpoint/invalid_return_type.stderr
Normal file
10
tests/ui/endpoint/invalid_return_type.stderr
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
error[E0277]: the trait bound `FooResponse: ResourceResult` is not satisfied
|
||||||
|
--> $DIR/invalid_return_type.rs:12:18
|
||||||
|
|
|
||||||
|
12 | fn endpoint() -> FooResponse {
|
||||||
|
| ^^^^^^^^^^^ the trait `ResourceResult` is not implemented for `FooResponse`
|
||||||
|
|
|
||||||
|
::: $WORKSPACE/src/endpoint.rs
|
||||||
|
|
|
||||||
|
| type Output: ResourceResult + Send;
|
||||||
|
| -------------- required by this bound in `gotham_restful::Endpoint::Output`
|
Loading…
Add table
Reference in a new issue