composable_tower_http/extract/
map.rs1use 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}