mirror of
https://github.com/tokio-rs/axum.git
synced 2024-10-23 17:36:39 +02:00
WIP2
This commit is contained in:
parent
5adb277a19
commit
7f55e3663b
31 changed files with 272 additions and 322 deletions
|
@ -2,7 +2,7 @@
|
|||
members = [
|
||||
"axum",
|
||||
"axum-core",
|
||||
"axum-extra",
|
||||
#"axum-extra",
|
||||
"axum-macros",
|
||||
]
|
||||
resolver = "2"
|
||||
|
|
|
@ -21,7 +21,7 @@ mod tests {
|
|||
fn from_request_parts<'a>(
|
||||
_parts: &'a mut Parts,
|
||||
state: &'a OuterState,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send + 'a {
|
||||
) -> Self::Future<'a> {
|
||||
async move {
|
||||
let inner_state = InnerState::from_ref(state);
|
||||
Ok(Self(inner_state))
|
||||
|
@ -39,10 +39,7 @@ mod tests {
|
|||
{
|
||||
type Rejection = Infallible;
|
||||
|
||||
fn from_request_parts<'a>(
|
||||
_parts: &'a mut Parts,
|
||||
state: &'a S,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send + 'a {
|
||||
fn from_request_parts<'a>(_parts: &'a mut Parts, state: &'a S) -> Self::Future<'a> {
|
||||
async move { Ok(Self(String::from_ref(state))) }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,8 +16,9 @@ pub trait RequestExt<B>: sealed::Sealed<B> + Sized {
|
|||
///
|
||||
/// Note this consumes the request. Use [`RequestExt::extract_parts`] if you're not extracting
|
||||
/// the body and don't want to consume the request.
|
||||
fn extract<E, M>(self) -> impl Future<Output = Result<E, E::Rejection>>
|
||||
fn extract<'a, E, M>(self) -> E::Future<'a>
|
||||
where
|
||||
B: 'a,
|
||||
E: FromRequest<(), B, M>;
|
||||
|
||||
/// Apply an extractor that requires some state to this `Request`.
|
||||
|
@ -26,17 +27,25 @@ pub trait RequestExt<B>: sealed::Sealed<B> + Sized {
|
|||
///
|
||||
/// Note this consumes the request. Use [`RequestExt::extract_parts_with_state`] if you're not
|
||||
/// extracting the body and don't want to consume the request.
|
||||
fn extract_with_state<E, S, M>(
|
||||
self,
|
||||
state: &S,
|
||||
) -> impl Future<Output = Result<E, E::Rejection>> + '_
|
||||
fn extract_with_state<'a, E, S, M>(self, state: &'a S) -> E::Future<'a>
|
||||
where
|
||||
B: 'a,
|
||||
E: FromRequest<S, B, M>;
|
||||
|
||||
#[doc(hidden)]
|
||||
#[rustfmt::skip]
|
||||
type ExtractPartsFuture<'a, E, S>:
|
||||
Future<Output = Result<E, <E as FromRequestParts<S>>::Rejection>> + 'a
|
||||
where
|
||||
Self: 'a,
|
||||
B: 'a,
|
||||
E: FromRequestParts<S>,
|
||||
S: 'a;
|
||||
|
||||
/// Apply a parts extractor to this `Request`.
|
||||
///
|
||||
/// This is just a convenience for `E::from_request_parts(parts, state)`.
|
||||
fn extract_parts<E>(&mut self) -> impl Future<Output = Result<E, E::Rejection>> + '_
|
||||
fn extract_parts<E>(&mut self) -> Self::ExtractPartsFuture<'_, E, ()>
|
||||
where
|
||||
E: FromRequestParts<()>;
|
||||
|
||||
|
@ -46,7 +55,7 @@ pub trait RequestExt<B>: sealed::Sealed<B> + Sized {
|
|||
fn extract_parts_with_state<'a, E, S>(
|
||||
&'a mut self,
|
||||
state: &'a S,
|
||||
) -> impl Future<Output = Result<E, E::Rejection>> + 'a
|
||||
) -> Self::ExtractPartsFuture<'a, E, S>
|
||||
where
|
||||
E: FromRequestParts<S>;
|
||||
|
||||
|
@ -61,38 +70,42 @@ pub trait RequestExt<B>: sealed::Sealed<B> + Sized {
|
|||
fn into_limited_body(self) -> Result<Limited<B>, B>;
|
||||
}
|
||||
|
||||
impl<B> RequestExt<B> for Request<B>
|
||||
where
|
||||
B: Send,
|
||||
{
|
||||
fn extract<E, M>(self) -> impl Future<Output = Result<E, E::Rejection>>
|
||||
impl<B> RequestExt<B> for Request<B> {
|
||||
fn extract<'a, E, M>(self) -> E::Future<'a>
|
||||
where
|
||||
B: 'a,
|
||||
E: FromRequest<(), B, M>,
|
||||
{
|
||||
self.extract_with_state(&())
|
||||
self.extract_with_state::<E, _, M>(&())
|
||||
}
|
||||
|
||||
fn extract_with_state<E, S, M>(
|
||||
self,
|
||||
state: &S,
|
||||
) -> impl Future<Output = Result<E, E::Rejection>> + '_
|
||||
fn extract_with_state<'a, E, S, M>(self, state: &'a S) -> E::Future<'a>
|
||||
where
|
||||
B: 'a,
|
||||
E: FromRequest<S, B, M>,
|
||||
{
|
||||
E::from_request(self, state)
|
||||
}
|
||||
|
||||
fn extract_parts<E>(&mut self) -> impl Future<Output = Result<E, E::Rejection>> + '_
|
||||
type ExtractPartsFuture<'a, E, S> =
|
||||
impl Future<Output = Result<E, <E as FromRequestParts<S>>::Rejection>> + 'a
|
||||
where
|
||||
Self: 'a,
|
||||
B: 'a,
|
||||
E: FromRequestParts<S>,
|
||||
S: 'a;
|
||||
|
||||
fn extract_parts<E>(&mut self) -> Self::ExtractPartsFuture<'_, E, ()>
|
||||
where
|
||||
E: FromRequestParts<()>,
|
||||
{
|
||||
self.extract_parts_with_state(&())
|
||||
self.extract_parts_with_state::<E, _>(&())
|
||||
}
|
||||
|
||||
fn extract_parts_with_state<'a, E, S>(
|
||||
&'a mut self,
|
||||
state: &'a S,
|
||||
) -> impl Future<Output = Result<E, E::Rejection>> + 'a
|
||||
) -> Self::ExtractPartsFuture<'a, E, S>
|
||||
where
|
||||
E: FromRequestParts<S>,
|
||||
{
|
||||
|
@ -216,10 +229,7 @@ mod tests {
|
|||
{
|
||||
type Rejection = <String as FromRequest<(), B>>::Rejection;
|
||||
|
||||
fn from_request(
|
||||
mut req: Request<B>,
|
||||
state: &S,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send + '_ {
|
||||
fn from_request(mut req: Request<B>, state: &S) -> Self::Future<'_> {
|
||||
async move {
|
||||
let RequiresState(from_state) = req.extract_parts_with_state(state).await.unwrap();
|
||||
let method = req.extract_parts().await.unwrap();
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use crate::extract::FromRequestParts;
|
||||
use http::request::Parts;
|
||||
use std::future::Future;
|
||||
|
||||
mod sealed {
|
||||
pub trait Sealed {}
|
||||
|
@ -12,33 +11,27 @@ pub trait RequestPartsExt: sealed::Sealed + Sized {
|
|||
/// Apply an extractor to this `Parts`.
|
||||
///
|
||||
/// This is just a convenience for `E::from_request_parts(parts, &())`.
|
||||
fn extract<E>(&mut self) -> impl Future<Output = Result<E, E::Rejection>> + '_
|
||||
fn extract<E>(&mut self) -> E::Future<'_>
|
||||
where
|
||||
E: FromRequestParts<()>;
|
||||
|
||||
/// Apply an extractor that requires some state to this `Parts`.
|
||||
///
|
||||
/// This is just a convenience for `E::from_request_parts(parts, state)`.
|
||||
fn extract_with_state<'a, E, S>(
|
||||
&'a mut self,
|
||||
state: &'a S,
|
||||
) -> impl Future<Output = Result<E, E::Rejection>> + 'a
|
||||
fn extract_with_state<'a, E, S>(&'a mut self, state: &'a S) -> E::Future<'a>
|
||||
where
|
||||
E: FromRequestParts<S>;
|
||||
}
|
||||
|
||||
impl RequestPartsExt for Parts {
|
||||
fn extract<E>(&mut self) -> impl Future<Output = Result<E, E::Rejection>> + '_
|
||||
fn extract<E>(&mut self) -> E::Future<'_>
|
||||
where
|
||||
E: FromRequestParts<()>,
|
||||
{
|
||||
self.extract_with_state(&())
|
||||
self.extract_with_state::<E, _>(&())
|
||||
}
|
||||
|
||||
fn extract_with_state<'a, E, S>(
|
||||
&'a mut self,
|
||||
state: &'a S,
|
||||
) -> impl Future<Output = Result<E, E::Rejection>> + 'a
|
||||
fn extract_with_state<'a, E, S>(&'a mut self, state: &'a S) -> E::Future<'a>
|
||||
where
|
||||
E: FromRequestParts<S>,
|
||||
{
|
||||
|
|
|
@ -38,15 +38,16 @@ mod private {
|
|||
///
|
||||
/// [`axum::extract`]: https://docs.rs/axum/0.6.0-rc.2/axum/extract/index.html
|
||||
pub trait FromRequestParts<S>: Sized {
|
||||
/// Future that resolves to either Self or Self::Rejection.
|
||||
type Future<'a>: Future<Output = Result<Self, Self::Rejection>> + 'a
|
||||
where
|
||||
S: 'a;
|
||||
/// If the extractor fails it'll use this "rejection" type. A rejection is
|
||||
/// a kind of error that can be converted into a response.
|
||||
type Rejection: IntoResponse;
|
||||
|
||||
/// Perform the extraction.
|
||||
fn from_request_parts<'a>(
|
||||
parts: &'a mut Parts,
|
||||
state: &'a S,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send + 'a;
|
||||
fn from_request_parts<'a>(parts: &'a mut Parts, state: &'a S) -> Self::Future<'a>;
|
||||
}
|
||||
|
||||
/// Types that can be created from requests.
|
||||
|
@ -101,29 +102,30 @@ pub trait FromRequestParts<S>: Sized {
|
|||
/// [`http::Request<B>`]: http::Request
|
||||
/// [`axum::extract`]: https://docs.rs/axum/0.6.0-rc.2/axum/extract/index.html
|
||||
pub trait FromRequest<S, B, M = private::ViaRequest>: Sized {
|
||||
/// Future that resolves to either Self or Self::Rejection.
|
||||
type Future<'a>: Future<Output = Result<Self, Self::Rejection>> + 'a
|
||||
where
|
||||
B: 'a,
|
||||
S: 'a;
|
||||
/// If the extractor fails it'll use this "rejection" type. A rejection is
|
||||
/// a kind of error that can be converted into a response.
|
||||
type Rejection: IntoResponse;
|
||||
|
||||
/// Perform the extraction.
|
||||
fn from_request(
|
||||
req: Request<B>,
|
||||
state: &S,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send + '_;
|
||||
fn from_request(req: Request<B>, state: &S) -> Self::Future<'_>;
|
||||
}
|
||||
|
||||
impl<S, B, T> FromRequest<S, B, private::ViaParts> for T
|
||||
where
|
||||
B: Send + 'static,
|
||||
S: Send + Sync,
|
||||
T: FromRequestParts<S>,
|
||||
{
|
||||
type Future<'a> = impl Future<Output = Result<Self, Self::Rejection>> + 'a
|
||||
where
|
||||
B: 'a,
|
||||
S: 'a;
|
||||
type Rejection = <Self as FromRequestParts<S>>::Rejection;
|
||||
|
||||
fn from_request(
|
||||
req: Request<B>,
|
||||
state: &S,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send + '_ {
|
||||
fn from_request(req: Request<B>, state: &S) -> Self::Future<'_> {
|
||||
async move {
|
||||
let (mut parts, _) = req.into_parts();
|
||||
Self::from_request_parts(&mut parts, state).await
|
||||
|
@ -136,12 +138,12 @@ where
|
|||
T: FromRequestParts<S>,
|
||||
S: Send + Sync,
|
||||
{
|
||||
type Future<'a> = impl Future<Output = Result<Self, Self::Rejection>> + 'a
|
||||
where
|
||||
S: 'a;
|
||||
type Rejection = Infallible;
|
||||
|
||||
fn from_request_parts<'a>(
|
||||
parts: &'a mut Parts,
|
||||
state: &'a S,
|
||||
) -> impl Future<Output = Result<Option<T>, Self::Rejection>> + Send + 'a {
|
||||
fn from_request_parts<'a>(parts: &'a mut Parts, state: &'a S) -> Self::Future<'a> {
|
||||
async move { Ok(T::from_request_parts(parts, state).await.ok()) }
|
||||
}
|
||||
}
|
||||
|
@ -152,12 +154,12 @@ where
|
|||
B: Send + 'static,
|
||||
S: Send + Sync,
|
||||
{
|
||||
type Future<'a> = impl Future<Output = Result<Self, Self::Rejection>> + 'a
|
||||
where
|
||||
S: 'a;
|
||||
type Rejection = Infallible;
|
||||
|
||||
fn from_request(
|
||||
req: Request<B>,
|
||||
state: &S,
|
||||
) -> impl Future<Output = Result<Option<T>, Self::Rejection>> + Send + '_ {
|
||||
fn from_request(req: Request<B>, state: &S) -> Self::Future<'_> {
|
||||
async move { Ok(T::from_request(req, state).await.ok()) }
|
||||
}
|
||||
}
|
||||
|
@ -167,12 +169,12 @@ where
|
|||
T: FromRequestParts<S>,
|
||||
S: Send + Sync,
|
||||
{
|
||||
type Future<'a> = impl Future<Output = Result<Self, Self::Rejection>> + 'a
|
||||
where
|
||||
S: 'a;
|
||||
type Rejection = Infallible;
|
||||
|
||||
fn from_request_parts<'a>(
|
||||
parts: &'a mut Parts,
|
||||
state: &'a S,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send + 'a {
|
||||
fn from_request_parts<'a>(parts: &'a mut Parts, state: &'a S) -> Self::Future<'a> {
|
||||
async move { Ok(T::from_request_parts(parts, state).await) }
|
||||
}
|
||||
}
|
||||
|
@ -183,12 +185,12 @@ where
|
|||
B: Send + 'static,
|
||||
S: Send + Sync,
|
||||
{
|
||||
type Future<'a> = impl Future<Output = Result<Self, Self::Rejection>> + 'a
|
||||
where
|
||||
S: 'a;
|
||||
type Rejection = Infallible;
|
||||
|
||||
fn from_request(
|
||||
req: Request<B>,
|
||||
state: &S,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send + '_ {
|
||||
fn from_request(req: Request<B>, state: &S) -> Self::Future<'_> {
|
||||
async move { Ok(T::from_request(req, state).await) }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,49 +4,47 @@ use bytes::Bytes;
|
|||
use http::{request::Parts, HeaderMap, Method, Request, Uri, Version};
|
||||
use std::{convert::Infallible, future::Future};
|
||||
|
||||
impl<S, B> FromRequest<S, B> for Request<B>
|
||||
where
|
||||
B: Send + 'static,
|
||||
{
|
||||
impl<S, B> FromRequest<S, B> for Request<B> {
|
||||
type Future<'a> = impl Future<Output = Result<Self, Self::Rejection>> + 'a
|
||||
where
|
||||
B: 'a,
|
||||
S: 'a;
|
||||
type Rejection = Infallible;
|
||||
|
||||
fn from_request(
|
||||
req: Request<B>,
|
||||
_state: &S,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send {
|
||||
fn from_request(req: Request<B>, _state: &S) -> Self::Future<'_> {
|
||||
async move { Ok(req) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> FromRequestParts<S> for Method {
|
||||
type Future<'a> = impl Future<Output = Result<Self, Self::Rejection>> + 'a
|
||||
where
|
||||
S: 'a;
|
||||
type Rejection = Infallible;
|
||||
|
||||
fn from_request_parts<'a>(
|
||||
parts: &'a mut Parts,
|
||||
_: &'a S,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send + 'a {
|
||||
fn from_request_parts<'a>(parts: &'a mut Parts, _: &'a S) -> Self::Future<'a> {
|
||||
async move { Ok(parts.method.clone()) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> FromRequestParts<S> for Uri {
|
||||
type Future<'a> = impl Future<Output = Result<Self, Self::Rejection>> + 'a
|
||||
where
|
||||
S: 'a;
|
||||
type Rejection = Infallible;
|
||||
|
||||
fn from_request_parts<'a>(
|
||||
parts: &'a mut Parts,
|
||||
_: &'a S,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send + 'a {
|
||||
fn from_request_parts<'a>(parts: &'a mut Parts, _: &'a S) -> Self::Future<'a> {
|
||||
async move { Ok(parts.uri.clone()) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> FromRequestParts<S> for Version {
|
||||
type Future<'a> = impl Future<Output = Result<Self, Self::Rejection>> + 'a
|
||||
where
|
||||
S: 'a;
|
||||
type Rejection = Infallible;
|
||||
|
||||
fn from_request_parts<'a>(
|
||||
parts: &'a mut Parts,
|
||||
_: &'a S,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send + 'a {
|
||||
fn from_request_parts<'a>(parts: &'a mut Parts, _: &'a S) -> Self::Future<'a> {
|
||||
async move { Ok(parts.version) }
|
||||
}
|
||||
}
|
||||
|
@ -57,28 +55,28 @@ impl<S> FromRequestParts<S> for Version {
|
|||
///
|
||||
/// [`TypedHeader`]: https://docs.rs/axum/latest/axum/extract/struct.TypedHeader.html
|
||||
impl<S> FromRequestParts<S> for HeaderMap {
|
||||
type Future<'a> = impl Future<Output = Result<Self, Self::Rejection>> + 'a
|
||||
where
|
||||
S: 'a;
|
||||
type Rejection = Infallible;
|
||||
|
||||
fn from_request_parts<'a>(
|
||||
parts: &'a mut Parts,
|
||||
_: &'a S,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send + 'a {
|
||||
fn from_request_parts<'a>(parts: &'a mut Parts, _: &'a S) -> Self::Future<'a> {
|
||||
async move { Ok(parts.headers.clone()) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<S, B> FromRequest<S, B> for Bytes
|
||||
where
|
||||
B: http_body::Body + Send + 'static,
|
||||
B::Data: Send,
|
||||
B: http_body::Body,
|
||||
B::Error: Into<BoxError>,
|
||||
{
|
||||
type Future<'a> = impl Future<Output = Result<Self, Self::Rejection>> + 'a
|
||||
where
|
||||
B: 'a,
|
||||
S: 'a;
|
||||
type Rejection = BytesRejection;
|
||||
|
||||
fn from_request(
|
||||
req: Request<B>,
|
||||
_state: &S,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send + '_ {
|
||||
fn from_request(req: Request<B>, _state: &S) -> Self::Future<'_> {
|
||||
async move {
|
||||
let bytes = match req.into_limited_body() {
|
||||
Ok(limited_body) => crate::body::to_bytes(limited_body)
|
||||
|
@ -100,12 +98,12 @@ where
|
|||
B::Data: Send,
|
||||
B::Error: Into<BoxError>,
|
||||
{
|
||||
type Future<'a> = impl Future<Output = Result<Self, Self::Rejection>> + 'a
|
||||
where
|
||||
S: 'a;
|
||||
type Rejection = StringRejection;
|
||||
|
||||
fn from_request(
|
||||
req: Request<B>,
|
||||
_state: &S,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send + '_ {
|
||||
fn from_request(req: Request<B>, _state: &S) -> Self::Future<'_> {
|
||||
async move {
|
||||
let bytes = Bytes::from_request(req, &())
|
||||
.await
|
||||
|
@ -128,12 +126,12 @@ impl<S, B> FromRequest<S, B> for Parts
|
|||
where
|
||||
B: Send + 'static,
|
||||
{
|
||||
type Future<'a> = impl Future<Output = Result<Self, Self::Rejection>> + 'a
|
||||
where
|
||||
S: 'a;
|
||||
type Rejection = Infallible;
|
||||
|
||||
fn from_request(
|
||||
req: Request<B>,
|
||||
_state: &S,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send + '_ {
|
||||
fn from_request(req: Request<B>, _state: &S) -> Self::Future<'_> {
|
||||
async move { Ok(req.into_parts().0) }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,12 +4,12 @@ use http::request::{Parts, Request};
|
|||
use std::{convert::Infallible, future::Future};
|
||||
|
||||
impl<S> FromRequestParts<S> for () {
|
||||
type Future<'a> = impl Future<Output = Result<Self, Self::Rejection>> + 'a
|
||||
where
|
||||
S: 'a;
|
||||
type Rejection = Infallible;
|
||||
|
||||
fn from_request_parts<'a>(
|
||||
_: &'a mut Parts,
|
||||
_: &'a S,
|
||||
) -> impl Future<Output = Result<(), Self::Rejection>> + Send + 'a {
|
||||
fn from_request_parts<'a>(_: &'a mut Parts, _: &'a S) -> Self::Future<'a> {
|
||||
async move { Ok(()) }
|
||||
}
|
||||
}
|
||||
|
@ -25,12 +25,15 @@ macro_rules! impl_from_request {
|
|||
$last: FromRequestParts<S> + Send,
|
||||
S: Send + Sync,
|
||||
{
|
||||
type Future<'a> = impl Future<Output = Result<Self, Self::Rejection>> + 'a
|
||||
where
|
||||
S: 'a;
|
||||
type Rejection = Response;
|
||||
|
||||
fn from_request_parts<'a>(
|
||||
parts: &'a mut Parts,
|
||||
state: &'a S,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send + 'a {
|
||||
) -> Self::Future<'a> {
|
||||
async move {
|
||||
$(
|
||||
let $ty = $ty::from_request_parts(parts, state)
|
||||
|
@ -56,12 +59,15 @@ macro_rules! impl_from_request {
|
|||
B: Send + 'static,
|
||||
S: Send + Sync,
|
||||
{
|
||||
type Future<'a> = impl Future<Output = Result<Self, Self::Rejection>> + 'a
|
||||
where
|
||||
S: 'a;
|
||||
type Rejection = Response;
|
||||
|
||||
fn from_request<'a>(
|
||||
req: Request<B>,
|
||||
state: &'a S,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send + 'a {
|
||||
) -> Self::Future<'a> {
|
||||
async move {
|
||||
let (mut parts, body) = req.into_parts();
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
//! [`axum`]: https://crates.io/crates/axum
|
||||
//! [`axum-core`]: http://crates.io/crates/axum-core
|
||||
|
||||
#![feature(return_position_impl_trait_in_trait)]
|
||||
#![feature(type_alias_impl_trait)]
|
||||
#![warn(
|
||||
clippy::all,
|
||||
clippy::dbg_macro,
|
||||
|
@ -47,7 +47,6 @@
|
|||
#![deny(unreachable_pub, private_in_public)]
|
||||
#![allow(
|
||||
elided_lifetimes_in_paths,
|
||||
incomplete_features,
|
||||
clippy::manual_async_fn,
|
||||
clippy::type_complexity
|
||||
)]
|
||||
|
|
|
@ -234,7 +234,7 @@ macro_rules! impl_traits_for_either {
|
|||
fn from_request_parts<'a>(
|
||||
parts: &'a mut Parts,
|
||||
state: &'a S,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send + 'a {
|
||||
) -> Self::Future<'a> {
|
||||
async move {
|
||||
$(
|
||||
if let Ok(value) = $ident::from_request_parts(parts, state).await {
|
||||
|
|
|
@ -91,10 +91,7 @@ where
|
|||
{
|
||||
type Rejection = T::Rejection;
|
||||
|
||||
fn from_request_parts<'a>(
|
||||
parts: &'a mut Parts,
|
||||
state: &'a S,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send + 'a {
|
||||
fn from_request_parts<'a>(parts: &'a mut Parts, state: &'a S) -> Self::Future<'a> {
|
||||
async move {
|
||||
match Extension::<CachedEntry<T>>::from_request_parts(parts, state).await {
|
||||
Ok(Extension(CachedEntry(value))) => Ok(Self(value)),
|
||||
|
@ -147,10 +144,7 @@ mod tests {
|
|||
{
|
||||
type Rejection = Infallible;
|
||||
|
||||
fn from_request_parts<'a>(
|
||||
_parts: &'a mut Parts,
|
||||
_state: &'a S,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send + 'a {
|
||||
fn from_request_parts<'a>(_parts: &'a mut Parts, _state: &'a S) -> Self::Future<'a> {
|
||||
async move {
|
||||
COUNTER.fetch_add(1, Ordering::SeqCst);
|
||||
Ok(Self(Instant::now()))
|
||||
|
|
|
@ -93,10 +93,7 @@ where
|
|||
{
|
||||
type Rejection = Infallible;
|
||||
|
||||
fn from_request_parts<'a>(
|
||||
parts: &'a mut Parts,
|
||||
_state: &'a S,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send + 'a {
|
||||
fn from_request_parts<'a>(parts: &'a mut Parts, _state: &'a S) -> Self::Future<'a> {
|
||||
async move { Ok(Self::from_headers(&parts.headers)) }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -92,10 +92,7 @@ where
|
|||
{
|
||||
type Rejection = Infallible;
|
||||
|
||||
fn from_request_parts<'a>(
|
||||
parts: &'a mut Parts,
|
||||
state: &'a S,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send + 'a {
|
||||
fn from_request_parts<'a>(parts: &'a mut Parts, state: &'a S) -> Self::Future<'a> {
|
||||
async move {
|
||||
let k = K::from_ref(state);
|
||||
let key = k.into();
|
||||
|
|
|
@ -117,10 +117,7 @@ where
|
|||
{
|
||||
type Rejection = R;
|
||||
|
||||
fn from_request(
|
||||
req: Request<B>,
|
||||
state: &S,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send + '_ {
|
||||
fn from_request(req: Request<B>, state: &S) -> Self::Future<'_> {
|
||||
async move {
|
||||
let extractor = E::from_request(req, state).await?;
|
||||
Ok(WithRejection(extractor, PhantomData))
|
||||
|
@ -136,10 +133,7 @@ where
|
|||
{
|
||||
type Rejection = R;
|
||||
|
||||
fn from_request_parts<'a>(
|
||||
parts: &'a mut Parts,
|
||||
state: &'a S,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send + 'a {
|
||||
fn from_request_parts<'a>(parts: &'a mut Parts, state: &'a S) -> Self::Future<'a> {
|
||||
async move {
|
||||
let extractor = E::from_request_parts(parts, state).await?;
|
||||
Ok(WithRejection(extractor, PhantomData))
|
||||
|
@ -167,10 +161,7 @@ mod tests {
|
|||
{
|
||||
type Rejection = ();
|
||||
|
||||
fn from_request_parts<'a>(
|
||||
_parts: &'a mut Parts,
|
||||
_state: &'a S,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send + 'a {
|
||||
fn from_request_parts<'a>(_parts: &'a mut Parts, _state: &'a S) -> Self::Future<'a> {
|
||||
async move { Err(()) }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -125,7 +125,7 @@ where
|
|||
{
|
||||
type Response = Response;
|
||||
type Error = Infallible;
|
||||
type Future = future::HandleErrorFuture;
|
||||
type Future = impl Future<Output = Result<Self::Response, Infallible>>;
|
||||
|
||||
fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||
Poll::Ready(Ok(()))
|
||||
|
@ -137,14 +137,12 @@ where
|
|||
let clone = self.inner.clone();
|
||||
let inner = std::mem::replace(&mut self.inner, clone);
|
||||
|
||||
let future = Box::pin(async move {
|
||||
async move {
|
||||
match inner.oneshot(req).await {
|
||||
Ok(res) => Ok(res.into_response()),
|
||||
Err(err) => Ok(f(err).await.into_response()),
|
||||
}
|
||||
});
|
||||
|
||||
future::HandleErrorFuture { future }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -167,7 +165,7 @@ macro_rules! impl_service {
|
|||
type Response = Response;
|
||||
type Error = Infallible;
|
||||
|
||||
type Future = future::HandleErrorFuture;
|
||||
type Future = impl Future<Output = Result<Self::Response, Infallible>>;
|
||||
|
||||
fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||
Poll::Ready(Ok(()))
|
||||
|
@ -180,7 +178,7 @@ macro_rules! impl_service {
|
|||
let clone = self.inner.clone();
|
||||
let inner = std::mem::replace(&mut self.inner, clone);
|
||||
|
||||
let future = Box::pin(async move {
|
||||
async move {
|
||||
let (mut parts, body) = req.into_parts();
|
||||
|
||||
$(
|
||||
|
@ -196,9 +194,7 @@ macro_rules! impl_service {
|
|||
Ok(res) => Ok(res.into_response()),
|
||||
Err(err) => Ok(f($($ty),*, err).await.into_response()),
|
||||
}
|
||||
});
|
||||
|
||||
future::HandleErrorFuture { future }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -221,38 +217,6 @@ impl_service!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14);
|
|||
impl_service!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15);
|
||||
impl_service!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16);
|
||||
|
||||
pub mod future {
|
||||
//! Future types.
|
||||
|
||||
use crate::response::Response;
|
||||
use pin_project_lite::pin_project;
|
||||
use std::{
|
||||
convert::Infallible,
|
||||
future::Future,
|
||||
pin::Pin,
|
||||
task::{Context, Poll},
|
||||
};
|
||||
|
||||
pin_project! {
|
||||
/// Response future for [`HandleError`].
|
||||
pub struct HandleErrorFuture {
|
||||
#[pin]
|
||||
pub(super) future: Pin<Box<dyn Future<Output = Result<Response, Infallible>>
|
||||
+ Send
|
||||
+ 'static
|
||||
>>,
|
||||
}
|
||||
}
|
||||
|
||||
impl Future for HandleErrorFuture {
|
||||
type Output = Result<Response, Infallible>;
|
||||
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
self.project().future.poll(cx)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn traits() {
|
||||
use crate::test_helpers::*;
|
||||
|
|
|
@ -75,14 +75,13 @@ pub struct Extension<T>(pub T);
|
|||
impl<T, S> FromRequestParts<S> for Extension<T>
|
||||
where
|
||||
T: Clone + Send + Sync + 'static,
|
||||
S: Send + Sync,
|
||||
{
|
||||
type Future<'a> = impl Future<Output = Result<Self, Self::Rejection>> + 'a
|
||||
where
|
||||
S: 'a;
|
||||
type Rejection = ExtensionRejection;
|
||||
|
||||
fn from_request_parts<'a>(
|
||||
req: &'a mut Parts,
|
||||
_state: &'a S,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + 'a {
|
||||
fn from_request_parts<'a>(req: &'a mut Parts, _state: &'a S) -> Self::Future<'a> {
|
||||
async move {
|
||||
let value = req
|
||||
.extensions
|
||||
|
|
|
@ -129,15 +129,14 @@ pub struct ConnectInfo<T>(pub T);
|
|||
|
||||
impl<S, T> FromRequestParts<S> for ConnectInfo<T>
|
||||
where
|
||||
S: Send + Sync,
|
||||
T: Clone + Send + Sync + 'static,
|
||||
{
|
||||
type Future<'a> = impl Future<Output = Result<Self, Self::Rejection>> + 'a
|
||||
where
|
||||
S: 'a;
|
||||
type Rejection = <Extension<Self> as FromRequestParts<S>>::Rejection;
|
||||
|
||||
fn from_request_parts<'a>(
|
||||
parts: &'a mut Parts,
|
||||
state: &'a S,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send + 'a {
|
||||
fn from_request_parts<'a>(parts: &'a mut Parts, state: &'a S) -> Self::Future<'a> {
|
||||
async move {
|
||||
let Extension(connect_info) =
|
||||
Extension::<Self>::from_request_parts(parts, state).await?;
|
||||
|
|
|
@ -23,16 +23,13 @@ const X_FORWARDED_HOST_HEADER_KEY: &str = "X-Forwarded-Host";
|
|||
#[derive(Debug, Clone)]
|
||||
pub struct Host(pub String);
|
||||
|
||||
impl<S> FromRequestParts<S> for Host
|
||||
where
|
||||
S: Send + Sync,
|
||||
{
|
||||
impl<S> FromRequestParts<S> for Host {
|
||||
type Future<'a> = impl Future<Output = Result<Self, Self::Rejection>> + 'a
|
||||
where
|
||||
S: 'a;
|
||||
type Rejection = HostRejection;
|
||||
|
||||
fn from_request_parts<'a>(
|
||||
parts: &'a mut Parts,
|
||||
_state: &'a S,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send + 'a {
|
||||
fn from_request_parts<'a>(parts: &'a mut Parts, _state: &'a S) -> Self::Future<'a> {
|
||||
async move {
|
||||
if let Some(host) = parse_forwarded(&parts.headers) {
|
||||
return Ok(Host(host.to_owned()));
|
||||
|
|
|
@ -63,16 +63,13 @@ impl MatchedPath {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S> FromRequestParts<S> for MatchedPath
|
||||
where
|
||||
S: Send + Sync,
|
||||
{
|
||||
impl<S> FromRequestParts<S> for MatchedPath {
|
||||
type Future<'a> = impl Future<Output = Result<Self, Self::Rejection>> + 'a
|
||||
where
|
||||
S: 'a;
|
||||
type Rejection = MatchedPathRejection;
|
||||
|
||||
fn from_request_parts<'a>(
|
||||
parts: &'a mut Parts,
|
||||
_state: &'a S,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send + 'a {
|
||||
fn from_request_parts<'a>(parts: &'a mut Parts, _state: &'a S) -> Self::Future<'a> {
|
||||
async move {
|
||||
let matched_path = parts
|
||||
.extensions
|
||||
|
|
|
@ -56,26 +56,35 @@ pub struct Multipart {
|
|||
|
||||
impl<S, B> FromRequest<S, B> for Multipart
|
||||
where
|
||||
B: HttpBody + Send + 'static,
|
||||
B: HttpBody + Send + Unpin + 'static,
|
||||
B::Data: Into<Bytes>,
|
||||
B::Error: Into<BoxError>,
|
||||
S: Send + Sync,
|
||||
{
|
||||
type Future<'a> = impl Future<Output = Result<Self, Self::Rejection>> + 'a
|
||||
where
|
||||
B: 'a,
|
||||
S: 'a;
|
||||
type Rejection = MultipartRejection;
|
||||
|
||||
fn from_request(
|
||||
req: Request<B>,
|
||||
state: &S,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send + '_ {
|
||||
fn from_request(req: Request<B>, state: &S) -> Self::Future<'_> {
|
||||
async move {
|
||||
let boundary = parse_boundary(req.headers()).ok_or(InvalidBoundary)?;
|
||||
let stream_result = match req.with_limited_body() {
|
||||
Ok(limited) => BodyStream::from_request(limited, state).await,
|
||||
Err(unlimited) => BodyStream::from_request(unlimited, state).await,
|
||||
let inner = match req.with_limited_body() {
|
||||
Ok(limited) => multer::Multipart::new(
|
||||
BodyStream::from_request(limited, state)
|
||||
.await
|
||||
.unwrap_or_else(|err| match err {}),
|
||||
boundary,
|
||||
),
|
||||
Err(unlimited) => multer::Multipart::new(
|
||||
BodyStream::from_request(unlimited, state)
|
||||
.await
|
||||
.unwrap_or_else(|err| match err {}),
|
||||
boundary,
|
||||
),
|
||||
};
|
||||
let stream = stream_result.unwrap_or_else(|err| match err {});
|
||||
let multipart = multer::Multipart::new(stream, boundary);
|
||||
Ok(Self { inner: multipart })
|
||||
|
||||
Ok(Self { inner })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -169,14 +169,13 @@ impl<T> DerefMut for Path<T> {
|
|||
impl<T, S> FromRequestParts<S> for Path<T>
|
||||
where
|
||||
T: DeserializeOwned + Send + 'static,
|
||||
S: Sync,
|
||||
{
|
||||
type Future<'a> = impl Future<Output = Result<Self, Self::Rejection>> + 'a
|
||||
where
|
||||
S: 'a;
|
||||
type Rejection = PathRejection;
|
||||
|
||||
fn from_request_parts<'a>(
|
||||
parts: &'a mut Parts,
|
||||
_state: &'a S,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send + 'a {
|
||||
fn from_request_parts<'a>(parts: &'a mut Parts, _state: &'a S) -> Self::Future<'a> {
|
||||
async move {
|
||||
let params = match parts.extensions.get::<UrlParams>() {
|
||||
Some(UrlParams::Params(params)) => params,
|
||||
|
|
|
@ -51,14 +51,13 @@ pub struct Query<T>(pub T);
|
|||
impl<T, S> FromRequestParts<S> for Query<T>
|
||||
where
|
||||
T: DeserializeOwned + 'static,
|
||||
S: Sync,
|
||||
{
|
||||
type Future<'a> = impl Future<Output = Result<Self, Self::Rejection>> + 'a
|
||||
where
|
||||
S: 'a;
|
||||
type Rejection = QueryRejection;
|
||||
|
||||
fn from_request_parts<'a>(
|
||||
parts: &'a mut Parts,
|
||||
_state: &'a S,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send + 'a {
|
||||
fn from_request_parts<'a>(parts: &'a mut Parts, _state: &'a S) -> Self::Future<'a> {
|
||||
async move {
|
||||
let query = parts.uri.query().unwrap_or_default();
|
||||
let value = serde_urlencoded::from_str(query)
|
||||
|
|
|
@ -36,17 +36,16 @@ pub struct RawForm(pub Bytes);
|
|||
|
||||
impl<S, B> FromRequest<S, B> for RawForm
|
||||
where
|
||||
B: HttpBody + Send + 'static,
|
||||
B::Data: Send,
|
||||
B: HttpBody,
|
||||
B::Error: Into<BoxError>,
|
||||
S: Send + Sync,
|
||||
{
|
||||
type Future<'a> = impl Future<Output = Result<Self, Self::Rejection>> + 'a
|
||||
where
|
||||
B: 'a,
|
||||
S: 'a;
|
||||
type Rejection = RawFormRejection;
|
||||
|
||||
fn from_request(
|
||||
req: Request<B>,
|
||||
state: &S,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send + '_ {
|
||||
fn from_request(req: Request<B>, state: &S) -> Self::Future<'_> {
|
||||
async move {
|
||||
if req.method() == Method::GET {
|
||||
let mut bytes = BytesMut::new();
|
||||
|
|
|
@ -26,16 +26,13 @@ use std::{convert::Infallible, future::Future};
|
|||
#[derive(Debug)]
|
||||
pub struct RawQuery(pub Option<String>);
|
||||
|
||||
impl<S> FromRequestParts<S> for RawQuery
|
||||
where
|
||||
S: Send + Sync,
|
||||
{
|
||||
impl<S> FromRequestParts<S> for RawQuery {
|
||||
type Future<'a> = impl Future<Output = Result<Self, Self::Rejection>> + 'a
|
||||
where
|
||||
S: 'a;
|
||||
type Rejection = Infallible;
|
||||
|
||||
fn from_request_parts<'a>(
|
||||
parts: &'a mut Parts,
|
||||
_state: &'a S,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send + 'a {
|
||||
fn from_request_parts<'a>(parts: &'a mut Parts, _state: &'a S) -> Self::Future<'a> {
|
||||
async move {
|
||||
let query = parts.uri.query().map(|query| query.to_owned());
|
||||
Ok(Self(query))
|
||||
|
|
|
@ -85,16 +85,13 @@ use sync_wrapper::SyncWrapper;
|
|||
pub struct OriginalUri(pub Uri);
|
||||
|
||||
#[cfg(feature = "original-uri")]
|
||||
impl<S> FromRequestParts<S> for OriginalUri
|
||||
where
|
||||
S: Send + Sync,
|
||||
{
|
||||
impl<S> FromRequestParts<S> for OriginalUri {
|
||||
type Future<'a> = impl Future<Output = Result<Self, Self::Rejection>> + 'a
|
||||
where
|
||||
S: 'a;
|
||||
type Rejection = Infallible;
|
||||
|
||||
fn from_request_parts<'a>(
|
||||
parts: &'a mut Parts,
|
||||
state: &'a S,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send + 'a {
|
||||
fn from_request_parts<'a>(parts: &'a mut Parts, state: &'a S) -> Self::Future<'a> {
|
||||
async move {
|
||||
let uri = Extension::<Self>::from_request_parts(parts, state)
|
||||
.await
|
||||
|
@ -137,11 +134,21 @@ where
|
|||
///
|
||||
/// [`Stream`]: https://docs.rs/futures/latest/futures/stream/trait.Stream.html
|
||||
/// [`body::Body`]: crate::body::Body
|
||||
pub struct BodyStream(
|
||||
SyncWrapper<Pin<Box<dyn HttpBody<Data = Bytes, Error = Error> + Send + 'static>>>,
|
||||
);
|
||||
pub struct BodyStream<B>(SyncWrapper<BodyStreamInner<B>>)
|
||||
where
|
||||
B: HttpBody;
|
||||
|
||||
impl Stream for BodyStream {
|
||||
type BodyStreamInner<B: HttpBody> = http_body::combinators::MapErr<
|
||||
http_body::combinators::MapData<B, fn(B::Data) -> Bytes>,
|
||||
fn(B::Error) -> Error,
|
||||
>;
|
||||
|
||||
impl<B> Stream for BodyStream<B>
|
||||
where
|
||||
// FIXME: Unpin not needed if pin projection is used.
|
||||
// Should replace the combinator stack with a manual HttpBody impl.
|
||||
B: HttpBody + Unpin,
|
||||
{
|
||||
type Item = Result<Bytes, Error>;
|
||||
|
||||
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
|
||||
|
@ -149,31 +156,34 @@ impl Stream for BodyStream {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S, B> FromRequest<S, B> for BodyStream
|
||||
impl<S, B> FromRequest<S, B> for BodyStream<B>
|
||||
where
|
||||
B: HttpBody + Send + 'static,
|
||||
B: HttpBody,
|
||||
B::Data: Into<Bytes>,
|
||||
B::Error: Into<BoxError>,
|
||||
S: Send + Sync,
|
||||
{
|
||||
type Future<'a> = impl Future<Output = Result<Self, Self::Rejection>> + 'a
|
||||
where
|
||||
B: 'a,
|
||||
S: 'a;
|
||||
type Rejection = Infallible;
|
||||
|
||||
fn from_request(
|
||||
req: Request<B>,
|
||||
_state: &S,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send + '_ {
|
||||
fn from_request(req: Request<B>, _: &S) -> Self::Future<'_> {
|
||||
async move {
|
||||
let body = req
|
||||
.into_body()
|
||||
.map_data(Into::into)
|
||||
.map_err(|err| Error::new(err.into()));
|
||||
let stream = BodyStream(SyncWrapper::new(Box::pin(body)));
|
||||
.map_data(Into::into as fn(B::Data) -> Bytes)
|
||||
.map_err((|err| Error::new(err.into())) as fn(B::Error) -> Error);
|
||||
let stream = BodyStream(SyncWrapper::new(body));
|
||||
Ok(stream)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for BodyStream {
|
||||
impl<B> fmt::Debug for BodyStream<B>
|
||||
where
|
||||
B: HttpBody,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_tuple("BodyStream").finish()
|
||||
}
|
||||
|
@ -181,8 +191,10 @@ impl fmt::Debug for BodyStream {
|
|||
|
||||
#[test]
|
||||
fn body_stream_traits() {
|
||||
crate::test_helpers::assert_send::<BodyStream>();
|
||||
crate::test_helpers::assert_sync::<BodyStream>();
|
||||
use http_body::Full;
|
||||
|
||||
crate::test_helpers::assert_send::<BodyStream<Full<Bytes>>>();
|
||||
crate::test_helpers::assert_sync::<BodyStream<Full<Bytes>>>();
|
||||
}
|
||||
|
||||
/// Extractor that extracts the raw request body.
|
||||
|
@ -216,17 +228,14 @@ fn body_stream_traits() {
|
|||
#[derive(Debug, Default, Clone)]
|
||||
pub struct RawBody<B = Body>(pub B);
|
||||
|
||||
impl<S, B> FromRequest<S, B> for RawBody<B>
|
||||
where
|
||||
B: Send + 'static,
|
||||
S: Send + Sync,
|
||||
{
|
||||
impl<S, B> FromRequest<S, B> for RawBody<B> {
|
||||
type Future<'a> = impl Future<Output = Result<Self, Self::Rejection>> + 'a
|
||||
where
|
||||
B: 'a,
|
||||
S: 'a;
|
||||
type Rejection = Infallible;
|
||||
|
||||
fn from_request(
|
||||
req: Request<B>,
|
||||
_state: &S,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send + '_ {
|
||||
fn from_request(req: Request<B>, _state: &S) -> Self::Future<'_> {
|
||||
async move { Ok(Self(req.into_body())) }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -226,14 +226,13 @@ pub struct State<S>(pub S);
|
|||
impl<OuterState, InnerState> FromRequestParts<OuterState> for State<InnerState>
|
||||
where
|
||||
InnerState: FromRef<OuterState> + 'static,
|
||||
OuterState: Send + Sync,
|
||||
{
|
||||
type Future<'a> = impl Future<Output = Result<Self, Self::Rejection>> + 'a
|
||||
where
|
||||
OuterState: 'a;
|
||||
type Rejection = Infallible;
|
||||
|
||||
fn from_request_parts<'a>(
|
||||
_parts: &'a mut Parts,
|
||||
state: &'a OuterState,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send + 'a {
|
||||
fn from_request_parts<'a>(_parts: &'a mut Parts, state: &'a OuterState) -> Self::Future<'a> {
|
||||
async move {
|
||||
let inner_state = InnerState::from_ref(state);
|
||||
Ok(Self(inner_state))
|
||||
|
|
|
@ -62,20 +62,19 @@ pub struct Form<T>(pub T);
|
|||
|
||||
impl<T, S, B> FromRequest<S, B> for Form<T>
|
||||
where
|
||||
T: DeserializeOwned + 'static,
|
||||
B: HttpBody + Send + 'static,
|
||||
B::Data: Send,
|
||||
T: DeserializeOwned,
|
||||
B: HttpBody,
|
||||
B::Error: Into<BoxError>,
|
||||
S: Send + Sync,
|
||||
{
|
||||
type Future<'a> = impl Future<Output = Result<Self, Self::Rejection>> + 'a
|
||||
where
|
||||
B: 'a,
|
||||
S: 'a;
|
||||
type Rejection = FormRejection;
|
||||
|
||||
fn from_request(
|
||||
req: Request<B>,
|
||||
_state: &S,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send + '_ {
|
||||
fn from_request(req: Request<B>, _state: &S) -> Self::Future<'_> {
|
||||
async move {
|
||||
match req.extract().await {
|
||||
match req.extract::<RawForm, _>().await {
|
||||
Ok(RawForm(bytes)) => {
|
||||
let value = serde_urlencoded::from_bytes(&bytes)
|
||||
.map_err(FailedToDeserializeQueryString::__private_new)?;
|
||||
|
|
|
@ -13,6 +13,7 @@ where
|
|||
pub(crate) fn new<H, T>(handler: H) -> Self
|
||||
where
|
||||
H: Handler<T, S, B>,
|
||||
H::Future: Send,
|
||||
T: 'static,
|
||||
{
|
||||
Self(Box::new(MakeErasedHandler {
|
||||
|
|
|
@ -98,7 +98,7 @@ pub use self::service::HandlerService;
|
|||
#[doc = include_str!("../docs/debugging_handler_type_errors.md")]
|
||||
pub trait Handler<T, S, B = Body>: Clone + Send + Sized + 'static {
|
||||
/// The type of future calling this handler returns.
|
||||
type Future: Future<Output = Response> + Send + 'static;
|
||||
type Future: Future<Output = Response> + 'static;
|
||||
|
||||
/// Call the handler with the given request.
|
||||
fn call(self, req: Request<B>, state: S) -> Self::Future;
|
||||
|
@ -185,7 +185,7 @@ macro_rules! impl_handler {
|
|||
$( $ty: FromRequestParts<S> + Send, )*
|
||||
$last: FromRequest<S, B, M> + Send,
|
||||
{
|
||||
type Future = impl Future<Output = Response> + Send + 'static;
|
||||
type Future = impl Future<Output = Response> + 'static;
|
||||
|
||||
fn call(self, req: Request<B>, state: S) -> Self::Future {
|
||||
async move {
|
||||
|
|
|
@ -103,18 +103,17 @@ pub struct Json<T>(pub T);
|
|||
|
||||
impl<T, S, B> FromRequest<S, B> for Json<T>
|
||||
where
|
||||
T: DeserializeOwned + 'static,
|
||||
B: HttpBody + Send + 'static,
|
||||
B::Data: Send,
|
||||
T: DeserializeOwned,
|
||||
B: HttpBody,
|
||||
B::Error: Into<BoxError>,
|
||||
S: Send + Sync,
|
||||
{
|
||||
type Future<'a> = impl Future<Output = Result<Self, Self::Rejection>> + 'a
|
||||
where
|
||||
B: 'a,
|
||||
S: 'a;
|
||||
type Rejection = JsonRejection;
|
||||
|
||||
fn from_request(
|
||||
req: Request<B>,
|
||||
state: &S,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send + '_ {
|
||||
fn from_request(req: Request<B>, state: &S) -> Self::Future<'_> {
|
||||
async move {
|
||||
if json_content_type(req.headers()) {
|
||||
let bytes = Bytes::from_request(req, state).await?;
|
||||
|
|
|
@ -320,12 +320,12 @@ mod tests {
|
|||
S: Send + Sync,
|
||||
Secret: FromRef<S>,
|
||||
{
|
||||
type Future<'a> = impl Future<Output = Result<Self, Self::Rejection>> + 'a
|
||||
where
|
||||
S: 'a;
|
||||
type Rejection = StatusCode;
|
||||
|
||||
fn from_request_parts<'a>(
|
||||
parts: &'a mut Parts,
|
||||
state: &'a S,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + 'a {
|
||||
fn from_request_parts<'a>(parts: &'a mut Parts, state: &'a S) -> Self::Future<'a> {
|
||||
async move {
|
||||
let Secret(secret) = Secret::from_ref(state);
|
||||
if let Some(auth) = parts
|
||||
|
@ -373,12 +373,12 @@ mod tests {
|
|||
where
|
||||
S: Send + Sync,
|
||||
{
|
||||
type Future<'a> = impl Future<Output = Result<Self, Self::Rejection>> + 'a
|
||||
where
|
||||
S: 'a;
|
||||
type Rejection = std::convert::Infallible;
|
||||
|
||||
fn from_request_parts<'a>(
|
||||
_parts: &'a mut Parts,
|
||||
_state: &'a S,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send + 'a {
|
||||
fn from_request_parts<'a>(_parts: &'a mut Parts, _state: &'a S) -> Self::Future<'a> {
|
||||
async move { unimplemented!() }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,12 +55,12 @@ impl<T, S> FromRequestParts<S> for TypedHeader<T>
|
|||
where
|
||||
T: headers::Header,
|
||||
{
|
||||
type Future<'a> = impl Future<Output = Result<Self, Self::Rejection>> + 'a
|
||||
where
|
||||
S: 'a;
|
||||
type Rejection = TypedHeaderRejection;
|
||||
|
||||
fn from_request_parts<'a>(
|
||||
parts: &'a mut Parts,
|
||||
_state: &'a S,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send + 'a {
|
||||
fn from_request_parts<'a>(parts: &'a mut Parts, _state: &'a S) -> Self::Future<'a> {
|
||||
async move {
|
||||
match parts.headers.typed_try_get::<T>() {
|
||||
Ok(Some(value)) => Ok(Self(value)),
|
||||
|
|
Loading…
Reference in a new issue