composable_tower_http/extract/
convert.rs

1use std::future::Future;
2
3use http::HeaderMap;
4
5use super::extractor::Extractor;
6
7#[derive(Debug, Clone)]
8pub struct Convert<T, Fn> {
9    inner: T,
10    convert: Fn,
11}
12
13impl<T, Fn> Convert<T, Fn> {
14    pub const fn new(inner: T, convert: Fn) -> Self {
15        Self { inner, convert }
16    }
17}
18
19#[derive(Debug, Clone)]
20pub struct AsyncConvert<T, Fn> {
21    inner: T,
22    convert: Fn,
23}
24
25impl<T, Fn> AsyncConvert<T, Fn> {
26    pub const fn new(inner: T, convert: Fn) -> Self {
27        Self { inner, convert }
28    }
29}
30
31impl<Ex, Fn, T, E> Extractor for Convert<Ex, Fn>
32where
33    Ex: Extractor + Sync,
34    Fn: FnOnce(Result<Ex::Extracted, Ex::Error>) -> Result<T, E> + Clone + Sync,
35    T: Clone + Send + Sync,
36{
37    type Extracted = T;
38
39    type Error = E;
40
41    async fn extract(&self, headers: &HeaderMap) -> Result<Self::Extracted, Self::Error> {
42        let ex = self.inner.extract(headers).await;
43
44        (self.convert.clone())(ex)
45    }
46}
47
48impl<Ex, Fn, T, E, Fut> Extractor for AsyncConvert<Ex, Fn>
49where
50    Ex: Extractor + Sync,
51    Fn: FnOnce(Result<Ex::Extracted, Ex::Error>) -> Fut + Clone + Sync,
52    Fut: Future<Output = Result<T, E>> + Send,
53    T: Clone + Send + Sync,
54{
55    type Extracted = T;
56
57    type Error = E;
58
59    async fn extract(&self, headers: &HeaderMap) -> Result<Self::Extracted, Self::Error> {
60        let ex = self.inner.extract(headers).await;
61
62        (self.convert.clone())(ex).await
63    }
64}