blueprint_core/extract/
option.rs

1use core::future::Future;
2
3use crate::extract::{FromJobCall, FromJobCallParts, JobCall, private};
4use crate::job::call::Parts;
5use crate::job::result::IntoJobResult;
6
7/// Customize the behavior of `Option<Self>` as a [`FromJobCallParts`]
8/// extractor.
9pub trait OptionalFromJobCallParts<Ctx>: Sized {
10    /// If the extractor fails, it will use this "rejection" type.
11    ///
12    /// A rejection is a kind of error that can be converted into a job result.
13    type Rejection: IntoJobResult;
14
15    /// Perform the extraction.
16    fn from_job_call_parts(
17        parts: &mut Parts,
18        ctx: &Ctx,
19    ) -> impl Future<Output = Result<Option<Self>, Self::Rejection>> + Send;
20}
21
22/// Customize the behavior of `Option<Self>` as a [`FromJobCall`] extractor.
23pub trait OptionalFromJobCall<Ctx, M = private::ViaJobCall>: Sized {
24    /// If the extractor fails, it will use this "rejection" type.
25    ///
26    /// A rejection is a kind of error that can be converted into a job result..
27    type Rejection: IntoJobResult;
28
29    /// Perform the extraction.
30    fn from_job_call(
31        call: JobCall,
32        ctx: &Ctx,
33    ) -> impl Future<Output = Result<Option<Self>, Self::Rejection>> + Send;
34}
35
36impl<Ctx, T> FromJobCallParts<Ctx> for Option<T>
37where
38    T: OptionalFromJobCallParts<Ctx>,
39    Ctx: Send + Sync,
40{
41    type Rejection = T::Rejection;
42
43    fn from_job_call_parts(
44        parts: &mut Parts,
45        ctx: &Ctx,
46    ) -> impl Future<Output = Result<Option<T>, Self::Rejection>> {
47        T::from_job_call_parts(parts, ctx)
48    }
49}
50
51impl<Ctx, T> FromJobCall<Ctx> for Option<T>
52where
53    T: OptionalFromJobCall<Ctx>,
54    Ctx: Send + Sync,
55{
56    type Rejection = T::Rejection;
57
58    async fn from_job_call(call: JobCall, ctx: &Ctx) -> Result<Option<T>, Self::Rejection> {
59        T::from_job_call(call, ctx).await
60    }
61}