Support opt-out of extra derived traits for rejections for #[derive(FromRequest)] (#729)

* Handle structs without fields

* Support opt-out of derived rejection traits

* Handle duplicate opt outs

* Improve error if opting out of `Display` or `Debug` but not `Error`

* document `rejection_derive`

* Handle using both `via` and `rejection_derive`

* don't derive debug for `RejectionDeriveOptOuts`

* Update axum-macros/src/from_request.rs

Co-authored-by: Jonas Platte <[email protected]>

Co-authored-by: Jonas Platte <[email protected]>
This commit is contained in:
David Pedersen
2022-01-28 09:54:38 +00:00
committed by GitHub
co-authored by Jonas Platte
parent f6fc5ed80c
commit 911c4a788e
23 changed files with 504 additions and 91 deletions
@@ -0,0 +1,9 @@
use axum_macros::FromRequest;
#[derive(FromRequest)]
#[from_request(rejection_derive(!Debug, !Display))]
struct Extractor {
body: String,
}
fn main() {}
@@ -0,0 +1,5 @@
error: opt out of `Debug` and `Display` requires also opting out of `Error`. Use `#[from_request(rejection_derive(!Debug, !Display, !Error))]`
--> tests/from_request/fail/derive_opt_out_debug_and_display_without_error.rs:4:34
|
4 | #[from_request(rejection_derive(!Debug, !Display))]
| ^^^^^
@@ -0,0 +1,9 @@
use axum_macros::FromRequest;
#[derive(FromRequest)]
#[from_request(rejection_derive(!Debug))]
struct Extractor {
body: String,
}
fn main() {}
@@ -0,0 +1,5 @@
error: opt out of `Debug` requires also opting out of `Error`. Use `#[from_request(rejection_derive(!Debug, !Error))]`
--> tests/from_request/fail/derive_opt_out_debug_without_error.rs:4:34
|
4 | #[from_request(rejection_derive(!Debug))]
| ^^^^^
@@ -0,0 +1,9 @@
use axum_macros::FromRequest;
#[derive(FromRequest)]
#[from_request(rejection_derive(!Display))]
struct Extractor {
body: String,
}
fn main() {}
@@ -0,0 +1,5 @@
error: opt out of `Display` requires also opting out of `Error`. Use `#[from_request(rejection_derive(!Display, !Error))]`
--> tests/from_request/fail/derive_opt_out_display_without_error.rs:4:34
|
4 | #[from_request(rejection_derive(!Display))]
| ^^^^^^^
@@ -0,0 +1,9 @@
use axum_macros::FromRequest;
#[derive(FromRequest)]
#[from_request(rejection_derive(!Error, !Error))]
struct Extractor {
body: String,
}
fn main() {}
@@ -0,0 +1,5 @@
error: `Error` opt out specified more than once
--> tests/from_request/fail/derive_opt_out_duplicate.rs:4:42
|
4 | #[from_request(rejection_derive(!Error, !Error))]
| ^^^^^
@@ -0,0 +1,10 @@
use axum_macros::FromRequest;
use axum::extract::Extension;
#[derive(FromRequest, Clone)]
#[from_request(rejection_derive(!Error), via(Extension))]
struct Extractor {
config: String,
}
fn main() {}
@@ -0,0 +1,13 @@
error: cannot use both `rejection_derive` and `via`
--> tests/from_request/fail/rejection_derive_and_via.rs:5:42
|
5 | #[from_request(rejection_derive(!Error), via(Extension))]
| ^^^
warning: unused import: `axum::extract::Extension`
--> tests/from_request/fail/rejection_derive_and_via.rs:2:5
|
2 | use axum::extract::Extension;
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
@@ -0,0 +1,7 @@
use axum_macros::FromRequest;
#[derive(FromRequest)]
#[from_request(foo)]
struct Extractor;
fn main() {}
@@ -0,0 +1,5 @@
error: expected `via` or `rejection_derive`
--> tests/from_request/fail/unknown_attr_container.rs:4:16
|
4 | #[from_request(foo)]
| ^^^
@@ -1,5 +1,5 @@
error: expected `via`
--> tests/from_request/fail/unknown_attr.rs:4:33
--> tests/from_request/fail/unknown_attr_field.rs:4:33
|
4 | struct Extractor(#[from_request(foo)] String);
| ^^^
@@ -0,0 +1,10 @@
use axum_macros::FromRequest;
use axum::extract::Extension;
#[derive(FromRequest, Clone)]
#[from_request(via(Extension), rejection_derive(!Error))]
struct Extractor {
config: String,
}
fn main() {}
@@ -0,0 +1,13 @@
error: cannot use both `via` and `rejection_derive`
--> tests/from_request/fail/via_and_rejection_derive.rs:5:32
|
5 | #[from_request(via(Extension), rejection_derive(!Error))]
| ^^^^^^^^^^^^^^^^
warning: unused import: `axum::extract::Extension`
--> tests/from_request/fail/via_and_rejection_derive.rs:2:5
|
2 | use axum::extract::Extension;
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
@@ -0,0 +1,37 @@
use axum::{
async_trait,
extract::{FromRequest, RequestParts},
response::{IntoResponse, Response},
};
use axum_macros::FromRequest;
#[derive(FromRequest)]
#[from_request(rejection_derive(!Display, !Error))]
struct Extractor {
other: OtherExtractor,
}
struct OtherExtractor;
#[async_trait]
impl<B> FromRequest<B> for OtherExtractor
where
B: Send + 'static,
{
type Rejection = OtherExtractorRejection;
async fn from_request(_req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> {
unimplemented!()
}
}
#[derive(Debug)]
struct OtherExtractorRejection;
impl IntoResponse for OtherExtractorRejection {
fn into_response(self) -> Response {
unimplemented!()
}
}
fn main() {}
@@ -0,0 +1,12 @@
use axum_macros::FromRequest;
#[derive(FromRequest)]
struct Extractor {}
fn assert_from_request()
where
Extractor: axum::extract::FromRequest<axum::body::Body, Rejection = std::convert::Infallible>,
{
}
fn main() {}
@@ -0,0 +1,12 @@
use axum_macros::FromRequest;
#[derive(FromRequest)]
struct Extractor();
fn assert_from_request()
where
Extractor: axum::extract::FromRequest<axum::body::Body, Rejection = std::convert::Infallible>,
{
}
fn main() {}
+1 -1
View File
@@ -5,7 +5,7 @@ struct Extractor;
fn assert_from_request()
where
Extractor: axum::extract::FromRequest<axum::body::Body>,
Extractor: axum::extract::FromRequest<axum::body::Body, Rejection = std::convert::Infallible>,
{
}