actix_service/
map_init_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::ServiceFactory;
11
12pub struct MapInitErr<A, F, Req, Err> {
14 a: A,
15 f: F,
16 e: PhantomData<fn(Req) -> Err>,
17}
18
19impl<A, F, Req, Err> MapInitErr<A, F, Req, Err>
20where
21 A: ServiceFactory<Req>,
22 F: Fn(A::InitError) -> Err,
23{
24 pub(crate) fn new(a: A, f: F) -> Self {
26 Self {
27 a,
28 f,
29 e: PhantomData,
30 }
31 }
32}
33
34impl<A, F, Req, E> Clone for MapInitErr<A, F, Req, E>
35where
36 A: Clone,
37 F: Clone,
38{
39 fn clone(&self) -> Self {
40 Self {
41 a: self.a.clone(),
42 f: self.f.clone(),
43 e: PhantomData,
44 }
45 }
46}
47
48impl<A, F, Req, E> ServiceFactory<Req> for MapInitErr<A, F, Req, E>
49where
50 A: ServiceFactory<Req>,
51 F: Fn(A::InitError) -> E + Clone,
52{
53 type Response = A::Response;
54 type Error = A::Error;
55
56 type Config = A::Config;
57 type Service = A::Service;
58 type InitError = E;
59 type Future = MapInitErrFuture<A, F, Req, E>;
60
61 fn new_service(&self, cfg: A::Config) -> Self::Future {
62 MapInitErrFuture::new(self.a.new_service(cfg), self.f.clone())
63 }
64}
65
66pin_project! {
67 pub struct MapInitErrFuture<A, F, Req, E>
68 where
69 A: ServiceFactory<Req>,
70 F: Fn(A::InitError) -> E,
71 {
72 f: F,
73 #[pin]
74 fut: A::Future,
75 }
76}
77
78impl<A, F, Req, E> MapInitErrFuture<A, F, Req, E>
79where
80 A: ServiceFactory<Req>,
81 F: Fn(A::InitError) -> E,
82{
83 fn new(fut: A::Future, f: F) -> Self {
84 MapInitErrFuture { f, fut }
85 }
86}
87
88impl<A, F, Req, E> Future for MapInitErrFuture<A, F, Req, E>
89where
90 A: ServiceFactory<Req>,
91 F: Fn(A::InitError) -> E,
92{
93 type Output = Result<A::Service, E>;
94
95 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
96 let this = self.project();
97 this.fut.poll(cx).map_err(this.f)
98 }
99}