resp_result/convert/from_request/
axum.rs

1use core::{future::Future, marker::Send, pin::Pin};
2
3use axum::extract::{FromRequest, FromRequestParts};
4use futures::TryFutureExt;
5
6use crate::{Nil, RespError, RespResult};
7
8use super::{FromRequestFamily, MapReject, ToInner};
9
10impl<S, B, T, E> FromRequest<S, B> for MapReject<T, E>
11where
12    B: Send + 'static,
13    S: Sync,
14    E: Send + From<<T::Payload as FromRequest<S, B>>::Rejection> + RespError,
15    T: FromRequestFamily<E>,
16    T::Payload: FromRequest<S, B>,
17{
18    type Rejection = RespResult<Nil, E>;
19
20    fn from_request<'life0, 'async_trait>(
21        req: http::Request<B>,
22        state: &'life0 S,
23    ) -> Pin<Box<dyn Future<Output = Result<Self, Self::Rejection>> + Send + 'async_trait>>
24    where
25        'life0: 'async_trait,
26        Self: 'async_trait,
27    {
28        Box::pin(async {
29            <T::Payload as FromRequest<S, B>>::from_request(req, state)
30                .map_err(|err| RespResult::<Nil, _>::Err(E::from(err)))
31                .map_ok(|data| MapReject::<T, E>(data.to_inner()))
32                .await
33        })
34    }
35}
36impl<S, T, E> FromRequestParts<S> for MapReject<T, E>
37where
38    S: Sync,
39    E: Send + From<<T::Payload as FromRequestParts<S>>::Rejection> + RespError,
40    T: FromRequestFamily<E>,
41    T::Payload: FromRequestParts<S>,
42{
43    type Rejection = RespResult<Nil, E>;
44
45    fn from_request_parts<'life0, 'life1, 'async_trait>(
46        parts: &'life0 mut http::request::Parts,
47        state: &'life1 S,
48    ) -> Pin<Box<dyn Future<Output = Result<Self, Self::Rejection>> + Send + 'async_trait>>
49    where
50        'life0: 'async_trait,
51        'life1: 'async_trait,
52        Self: 'async_trait,
53    {
54        Box::pin(async {
55            <T::Payload as FromRequestParts<S>>::from_request_parts(parts, state)
56                .map_err(|err| RespResult::Err(E::from(err)))
57                .map_ok(|data| Self(data.to_inner()))
58                .await
59        })
60    }
61}
62mod from_request_families {
63    use axum::extract::{Extension, Form, Json, Path, Query, State};
64
65    use crate::convert::from_request::ToInner;
66
67    impl<T> ToInner for Extension<T> {
68        type Inner = T;
69
70        fn to_inner(self) -> Self::Inner {
71            self.0
72        }
73    }
74
75    impl<T> ToInner for Form<T> {
76        type Inner = T;
77
78        fn to_inner(self) -> Self::Inner {
79            self.0
80        }
81    }
82
83    impl<T> ToInner for Json<T> {
84        type Inner = T;
85
86        fn to_inner(self) -> Self::Inner {
87            self.0
88        }
89    }
90
91    impl<T> ToInner for Path<T> {
92        type Inner = T;
93
94        fn to_inner(self) -> Self::Inner {
95            self.0
96        }
97    }
98
99    impl<T> ToInner for Query<T> {
100        type Inner = T;
101
102        fn to_inner(self) -> Self::Inner {
103            self.0
104        }
105    }
106
107    impl<T> ToInner for State<T> {
108        type Inner = T;
109
110        fn to_inner(self) -> Self::Inner {
111            self.0
112        }
113    }
114}