composable_tower_http/extract/
map.rs

1use std::future::Future;
2
3use http::HeaderMap;
4
5use super::extractor::Extractor;
6
7#[derive(Debug, Clone)]
8pub struct Map<T, Fn> {
9    inner: T,
10    map: Fn,
11}
12
13impl<T, Fn> Map<T, Fn> {
14    pub const fn new(inner: T, map: Fn) -> Self {
15        Self { inner, map }
16    }
17}
18
19#[derive(Debug, Clone)]
20pub struct AsyncMap<T, Fn> {
21    inner: T,
22    map: Fn,
23}
24
25impl<T, Fn> AsyncMap<T, Fn> {
26    pub const fn new(inner: T, map: Fn) -> Self {
27        Self { inner, map }
28    }
29}
30
31#[derive(Debug, Clone)]
32pub struct MapError<T, Fn> {
33    inner: T,
34    map_err: Fn,
35}
36
37impl<T, Fn> MapError<T, Fn> {
38    pub const fn new(inner: T, map_err: Fn) -> Self {
39        Self { inner, map_err }
40    }
41}
42
43impl<Ex, Fn, T> Extractor for Map<Ex, Fn>
44where
45    Ex: Extractor + Sync,
46    Fn: FnOnce(Ex::Extracted) -> T + Clone + Sync,
47    T: Clone + Send + Sync,
48{
49    type Extracted = T;
50
51    type Error = Ex::Error;
52
53    async fn extract(&self, headers: &HeaderMap) -> Result<Self::Extracted, Self::Error> {
54        self.inner
55            .extract(headers)
56            .await
57            .map(|ex| (self.map.clone())(ex))
58    }
59}
60
61impl<Ex, Fn, T, Fut> Extractor for AsyncMap<Ex, Fn>
62where
63    Ex: Extractor + Sync,
64    Fn: FnOnce(Ex::Extracted) -> Fut + Clone + Sync,
65    Fut: Future<Output = T> + Send,
66    T: Clone + Send + Sync,
67{
68    type Extracted = T;
69
70    type Error = Ex::Error;
71
72    async fn extract(&self, headers: &HeaderMap) -> Result<Self::Extracted, Self::Error> {
73        let extracted = self.inner.extract(headers).await?;
74
75        let mapped = (self.map.clone())(extracted).await;
76
77        Ok(mapped)
78    }
79}
80
81impl<Ex, Fn, E> Extractor for MapError<Ex, Fn>
82where
83    Ex: Extractor + Sync,
84    Fn: FnOnce(Ex::Error) -> E + Clone + Sync,
85{
86    type Extracted = Ex::Extracted;
87
88    type Error = E;
89
90    async fn extract(&self, headers: &HeaderMap) -> Result<Self::Extracted, Self::Error> {
91        self.inner
92            .extract(headers)
93            .await
94            .map_err(|err| (self.map_err.clone())(err))
95    }
96}