rama_http/service/web/endpoint/extract/
option.rs

1use std::future::Future;
2
3use rama_core::Context;
4
5use crate::response::IntoResponse;
6use crate::{dep::http::request::Parts, Request};
7
8use super::{FromRequest, FromRequestContextRefPair};
9
10/// Customize the behavior of `Option<Self>` as a [`FromRequestContextRefPair`]
11/// extractor.
12pub trait OptionalFromRequestContextRefPair<S>: Sized + Send + Sync + 'static {
13    /// If the extractor fails, it will use this "rejection" type.
14    ///
15    /// A rejection is a kind of error that can be converted into a response.
16    type Rejection: IntoResponse;
17
18    /// Perform the extraction.
19    fn from_request_context_ref_pair(
20        ctx: &Context<S>,
21        parts: &Parts,
22    ) -> impl Future<Output = Result<Option<Self>, Self::Rejection>> + Send;
23}
24
25/// Customize the behavior of `Option<Self>` as a [`FromRequest`] extractor.
26pub trait OptionalFromRequest: Sized + Send + Sync + 'static {
27    /// If the extractor fails, it will use this "rejection" type.
28    ///
29    /// A rejection is a kind of error that can be converted into a response.
30    type Rejection: IntoResponse;
31
32    /// Perform the extraction.
33    fn from_request(
34        req: Request,
35    ) -> impl Future<Output = Result<Option<Self>, Self::Rejection>> + Send;
36}
37
38impl<S, T> FromRequestContextRefPair<S> for Option<T>
39where
40    T: OptionalFromRequestContextRefPair<S>,
41    S: Send + Sync,
42{
43    type Rejection = T::Rejection;
44
45    fn from_request_context_ref_pair(
46        ctx: &Context<S>,
47        parts: &Parts,
48    ) -> impl Future<Output = Result<Self, Self::Rejection>> + Send {
49        T::from_request_context_ref_pair(ctx, parts)
50    }
51}
52
53impl<T> FromRequest for Option<T>
54where
55    T: OptionalFromRequest,
56{
57    type Rejection = T::Rejection;
58
59    async fn from_request(req: Request) -> Result<Option<T>, Self::Rejection> {
60        T::from_request(req).await
61    }
62}