This commit is contained in:
Jonas Platte 2022-11-05 14:17:43 +01:00
parent 5adb277a19
commit 7f55e3663b
No known key found for this signature in database
GPG key ID: CC154DE0E30B7C67
31 changed files with 272 additions and 322 deletions

View file

@ -2,7 +2,7 @@
members = [
"axum",
"axum-core",
"axum-extra",
#"axum-extra",
"axum-macros",
]
resolver = "2"

View file

@ -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))) }
}
}

View file

@ -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();

View file

@ -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>,
{

View file

@ -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) }
}
}

View file

@ -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) }
}
}

View file

@ -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();

View file

@ -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
)]

View file

@ -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 {

View file

@ -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()))

View file

@ -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)) }
}
}

View file

@ -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();

View file

@ -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(()) }
}
}

View file

@ -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::*;

View file

@ -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

View file

@ -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?;

View file

@ -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()));

View file

@ -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

View file

@ -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 })
}
}
}

View file

@ -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,

View file

@ -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)

View file

@ -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();

View file

@ -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))

View file

@ -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())) }
}
}

View file

@ -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))

View file

@ -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)?;

View file

@ -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 {

View file

@ -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 {

View file

@ -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?;

View file

@ -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!() }
}
}

View file

@ -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)),