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