actix_service/
transform_err.rs1use core::{
2 future::Future,
3 marker::PhantomData,
4 pin::Pin,
5 task::{Context, Poll},
6};
7
8use pin_project_lite::pin_project;
9
10use super::Transform;
11
12pub struct TransformMapInitErr<T, S, Req, F, E> {
15 transform: T,
16 mapper: F,
17 _phantom: PhantomData<fn(Req) -> (S, E)>,
18}
19
20impl<T, S, F, E, Req> TransformMapInitErr<T, S, Req, F, E> {
21 pub(crate) fn new(t: T, f: F) -> Self
22 where
23 T: Transform<S, Req>,
24 F: Fn(T::InitError) -> E,
25 {
26 Self {
27 transform: t,
28 mapper: f,
29 _phantom: PhantomData,
30 }
31 }
32}
33
34impl<T, S, Req, F, E> Clone for TransformMapInitErr<T, S, Req, F, E>
35where
36 T: Clone,
37 F: Clone,
38{
39 fn clone(&self) -> Self {
40 Self {
41 transform: self.transform.clone(),
42 mapper: self.mapper.clone(),
43 _phantom: PhantomData,
44 }
45 }
46}
47
48impl<T, S, F, E, Req> Transform<S, Req> for TransformMapInitErr<T, S, Req, F, E>
49where
50 T: Transform<S, Req>,
51 F: Fn(T::InitError) -> E + Clone,
52{
53 type Response = T::Response;
54 type Error = T::Error;
55 type Transform = T::Transform;
56
57 type InitError = E;
58 type Future = TransformMapInitErrFuture<T, S, F, E, Req>;
59
60 fn new_transform(&self, service: S) -> Self::Future {
61 TransformMapInitErrFuture {
62 fut: self.transform.new_transform(service),
63 f: self.mapper.clone(),
64 }
65 }
66}
67
68pin_project! {
69 pub struct TransformMapInitErrFuture<T, S, F, E, Req>
70 where
71 T: Transform<S, Req>,
72 F: Fn(T::InitError) -> E,
73 {
74 #[pin]
75 fut: T::Future,
76 f: F,
77 }
78}
79
80impl<T, S, F, E, Req> Future for TransformMapInitErrFuture<T, S, F, E, Req>
81where
82 T: Transform<S, Req>,
83 F: Fn(T::InitError) -> E + Clone,
84{
85 type Output = Result<T::Transform, E>;
86
87 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
88 let this = self.project();
89 if let Poll::Ready(res) = this.fut.poll(cx) {
90 Poll::Ready(res.map_err(this.f))
91 } else {
92 Poll::Pending
93 }
94 }
95}