mirror of
https://github.com/tokio-rs/axum.git
synced 2026-09-06 00:00:17 +02:00
Add a separate trait for optional extractors (#2475)
This commit is contained in:
@@ -13,11 +13,16 @@ pub mod rejection;
|
||||
|
||||
mod default_body_limit;
|
||||
mod from_ref;
|
||||
mod option;
|
||||
mod request_parts;
|
||||
mod tuple;
|
||||
|
||||
pub(crate) use self::default_body_limit::DefaultBodyLimitKind;
|
||||
pub use self::{default_body_limit::DefaultBodyLimit, from_ref::FromRef};
|
||||
pub use self::{
|
||||
default_body_limit::DefaultBodyLimit,
|
||||
from_ref::FromRef,
|
||||
option::{OptionalFromRequest, OptionalFromRequestParts},
|
||||
};
|
||||
|
||||
/// Type alias for [`http::Request`] whose body type defaults to [`Body`], the most common body
|
||||
/// type used with axum.
|
||||
@@ -102,33 +107,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<S, T> FromRequestParts<S> for Option<T>
|
||||
where
|
||||
T: FromRequestParts<S>,
|
||||
S: Send + Sync,
|
||||
{
|
||||
type Rejection = Infallible;
|
||||
|
||||
async fn from_request_parts(
|
||||
parts: &mut Parts,
|
||||
state: &S,
|
||||
) -> Result<Option<T>, Self::Rejection> {
|
||||
Ok(T::from_request_parts(parts, state).await.ok())
|
||||
}
|
||||
}
|
||||
|
||||
impl<S, T> FromRequest<S> for Option<T>
|
||||
where
|
||||
T: FromRequest<S>,
|
||||
S: Send + Sync,
|
||||
{
|
||||
type Rejection = Infallible;
|
||||
|
||||
async fn from_request(req: Request, state: &S) -> Result<Option<T>, Self::Rejection> {
|
||||
Ok(T::from_request(req, state).await.ok())
|
||||
}
|
||||
}
|
||||
|
||||
impl<S, T> FromRequestParts<S> for Result<T, T::Rejection>
|
||||
where
|
||||
T: FromRequestParts<S>,
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
use std::future::Future;
|
||||
|
||||
use http::request::Parts;
|
||||
|
||||
use crate::response::IntoResponse;
|
||||
|
||||
use super::{private, FromRequest, FromRequestParts, Request};
|
||||
|
||||
/// Customize the behavior of `Option<Self>` as a [`FromRequestParts`]
|
||||
/// extractor.
|
||||
pub trait OptionalFromRequestParts<S>: Sized {
|
||||
/// If the extractor fails, it will 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(
|
||||
parts: &mut Parts,
|
||||
state: &S,
|
||||
) -> impl Future<Output = Result<Option<Self>, Self::Rejection>> + Send;
|
||||
}
|
||||
|
||||
/// Customize the behavior of `Option<Self>` as a [`FromRequest`] extractor.
|
||||
pub trait OptionalFromRequest<S, M = private::ViaRequest>: Sized {
|
||||
/// If the extractor fails, it will 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,
|
||||
state: &S,
|
||||
) -> impl Future<Output = Result<Option<Self>, Self::Rejection>> + Send;
|
||||
}
|
||||
|
||||
impl<S, T> FromRequestParts<S> for Option<T>
|
||||
where
|
||||
T: OptionalFromRequestParts<S>,
|
||||
S: Send + Sync,
|
||||
{
|
||||
type Rejection = T::Rejection;
|
||||
|
||||
fn from_request_parts(
|
||||
parts: &mut Parts,
|
||||
state: &S,
|
||||
) -> impl Future<Output = Result<Option<T>, Self::Rejection>> {
|
||||
T::from_request_parts(parts, state)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S, T> FromRequest<S> for Option<T>
|
||||
where
|
||||
T: OptionalFromRequest<S>,
|
||||
S: Send + Sync,
|
||||
{
|
||||
type Rejection = T::Rejection;
|
||||
|
||||
async fn from_request(req: Request, state: &S) -> Result<Option<T>, Self::Rejection> {
|
||||
T::from_request(req, state).await
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user