1
0
mirror of https://github.com/fafhrd91/actix-web synced 2024-11-27 17:52:56 +01:00

fix support for 12 extractors (#2582)

Co-authored-by: Rob Ede <robjtede@icloud.com>
This commit is contained in:
Ali MJ Al-Nasrawy 2022-01-12 21:31:48 +03:00 committed by GitHub
parent 6c97d448b7
commit 2a12b41456
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 48 additions and 24 deletions

View File

@ -7,10 +7,12 @@
### Changed ### Changed
- `HttpResponse` can now be used as a `Responder` with any body type. [#2567] - `HttpResponse` can now be used as a `Responder` with any body type. [#2567]
- Maximim number of extractors has changed from 10 to 12. [#2582]
[#1988]: https://github.com/actix/actix-web/pull/1988 [#1988]: https://github.com/actix/actix-web/pull/1988
[#2567]: https://github.com/actix/actix-web/pull/2567 [#2567]: https://github.com/actix/actix-web/pull/2567
[#2569]: https://github.com/actix/actix-web/pull/2569 [#2569]: https://github.com/actix/actix-web/pull/2569
[#2582]: https://github.com/actix/actix-web/pull/2582
## 4.0.0-beta.19 - 2022-01-04 ## 4.0.0-beta.19 - 2022-01-04

View File

@ -290,16 +290,6 @@ impl FromRequest for Method {
} }
} }
#[doc(hidden)]
impl FromRequest for () {
type Error = Infallible;
type Future = Ready<Result<Self, Self::Error>>;
fn from_request(_: &HttpRequest, _: &mut Payload) -> Self::Future {
ok(())
}
}
#[doc(hidden)] #[doc(hidden)]
#[allow(non_snake_case)] #[allow(non_snake_case)]
mod tuple_from_req { mod tuple_from_req {
@ -388,6 +378,15 @@ mod tuple_from_req {
} }
} }
impl FromRequest for () {
type Error = Infallible;
type Future = Ready<Result<Self, Self::Error>>;
fn from_request(_: &HttpRequest, _: &mut Payload) -> Self::Future {
ok(())
}
}
tuple_from_req! { TupleFromRequest1; A } tuple_from_req! { TupleFromRequest1; A }
tuple_from_req! { TupleFromRequest2; A, B } tuple_from_req! { TupleFromRequest2; A, B }
tuple_from_req! { TupleFromRequest3; A, B, C } tuple_from_req! { TupleFromRequest3; A, B, C }
@ -398,6 +397,8 @@ mod tuple_from_req {
tuple_from_req! { TupleFromRequest8; A, B, C, D, E, F, G, H } tuple_from_req! { TupleFromRequest8; A, B, C, D, E, F, G, H }
tuple_from_req! { TupleFromRequest9; A, B, C, D, E, F, G, H, I } tuple_from_req! { TupleFromRequest9; A, B, C, D, E, F, G, H, I }
tuple_from_req! { TupleFromRequest10; A, B, C, D, E, F, G, H, I, J } tuple_from_req! { TupleFromRequest10; A, B, C, D, E, F, G, H, I, J }
tuple_from_req! { TupleFromRequest11; A, B, C, D, E, F, G, H, I, J, K }
tuple_from_req! { TupleFromRequest12; A, B, C, D, E, F, G, H, I, J, K, L }
} }
#[cfg(test)] #[cfg(test)]

View File

@ -12,17 +12,14 @@ use crate::{
/// # What Is A Request Handler /// # What Is A Request Handler
/// A request handler has three requirements: /// A request handler has three requirements:
/// 1. It is an async function (or a function/closure that returns an appropriate future); /// 1. It is an async function (or a function/closure that returns an appropriate future);
/// 1. The function accepts zero or more parameters that implement [`FromRequest`]; /// 1. The function parameters (up to 12) implement [`FromRequest`];
/// 1. The async function (or future) resolves to a type that can be converted into an /// 1. The async function (or future) resolves to a type that can be converted into an
/// [`HttpResponse`] (i.e., it implements the [`Responder`] trait). /// [`HttpResponse`] (i.e., it implements the [`Responder`] trait).
/// ///
/// # Compiler Errors /// # Compiler Errors
/// If you get the error `the trait Handler<_> is not implemented`, then your handler does not /// If you get the error `the trait Handler<_> is not implemented`, then your handler does not
/// fulfill one or more of the above requirements. /// fulfill the _first_ of the above requirements. Missing other requirements manifest as errors on
/// /// implementing [`FromRequest`] and [`Responder`], respectively.
/// Unfortunately we cannot provide a better compile error message (while keeping the trait's
/// flexibility) unless a stable alternative to [`#[rustc_on_unimplemented]`][on_unimpl] is added
/// to Rust.
/// ///
/// # How Do Handlers Receive Variable Numbers Of Arguments /// # How Do Handlers Receive Variable Numbers Of Arguments
/// Rest assured there is no macro magic here; it's just traits. /// Rest assured there is no macro magic here; it's just traits.
@ -62,13 +59,15 @@ use crate::{
/// This is the source code for the 2-parameter implementation of `Handler` to help illustrate the /// This is the source code for the 2-parameter implementation of `Handler` to help illustrate the
/// bounds of the handler call after argument extraction: /// bounds of the handler call after argument extraction:
/// ```ignore /// ```ignore
/// impl<Func, Arg1, Arg2, R> Handler<(Arg1, Arg2), R> for Func /// impl<Func, Arg1, Arg2, Fut> Handler<(Arg1, Arg2)> for Func
/// where /// where
/// Func: Fn(Arg1, Arg2) -> R + Clone + 'static, /// Func: Fn(Arg1, Arg2) -> Fut + Clone + 'static,
/// R: Future, /// Fut: Future,
/// R::Output: Responder,
/// { /// {
/// fn call(&self, (arg1, arg2): (Arg1, Arg2)) -> R { /// type Output = Fut::Output;
/// type Future = Fut;
///
/// fn call(&self, (arg1, arg2): (Arg1, Arg2)) -> Self::Future {
/// (self)(arg1, arg2) /// (self)(arg1, arg2)
/// } /// }
/// } /// }
@ -76,7 +75,6 @@ use crate::{
/// ///
/// [arity]: https://en.wikipedia.org/wiki/Arity /// [arity]: https://en.wikipedia.org/wiki/Arity
/// [`from_request`]: FromRequest::from_request /// [`from_request`]: FromRequest::from_request
/// [on_unimpl]: https://github.com/rust-lang/rust/issues/29628
pub trait Handler<Args>: Clone + 'static { pub trait Handler<Args>: Clone + 'static {
type Output; type Output;
type Future: Future<Output = Self::Output>; type Future: Future<Output = Self::Output>;
@ -121,7 +119,8 @@ where
/// ``` /// ```
macro_rules! factory_tuple ({ $($param:ident)* } => { macro_rules! factory_tuple ({ $($param:ident)* } => {
impl<Func, Fut, $($param,)*> Handler<($($param,)*)> for Func impl<Func, Fut, $($param,)*> Handler<($($param,)*)> for Func
where Func: Fn($($param),*) -> Fut + Clone + 'static, where
Func: Fn($($param),*) -> Fut + Clone + 'static,
Fut: Future, Fut: Future,
{ {
type Output = Fut::Output; type Output = Fut::Output;
@ -148,3 +147,25 @@ factory_tuple! { A B C D E F G H I }
factory_tuple! { A B C D E F G H I J } factory_tuple! { A B C D E F G H I J }
factory_tuple! { A B C D E F G H I J K } factory_tuple! { A B C D E F G H I J K }
factory_tuple! { A B C D E F G H I J K L } factory_tuple! { A B C D E F G H I J K L }
#[cfg(test)]
mod tests {
use super::*;
fn assert_impl_handler<T: FromRequest>(_: impl Handler<T>) {}
#[test]
fn arg_number() {
async fn handler_min() {}
#[rustfmt::skip]
#[allow(clippy::too_many_arguments, clippy::just_underscores_and_digits)]
async fn handler_max(
_01: (), _02: (), _03: (), _04: (), _05: (), _06: (),
_07: (), _08: (), _09: (), _10: (), _11: (), _12: (),
) {}
assert_impl_handler(handler_min);
assert_impl_handler(handler_max);
}
}