request_pretreat/prefabs/
error_mapping.rs1use std::{marker::PhantomData, task::Poll};
2
3use futures::{pin_mut, Future};
4
5use crate::Treater;
6
7pub struct MapError<T: Treater, E: From<T::Err>>(PhantomData<(T, E)>);
8
9impl<T, E> Treater for MapError<T, E>
10where
11 T: Treater,
12 E: From<T::Err>,
13 T: 'static,
14{
15 type Fut = MapErrFut<T, E>;
16
17 type Resp = T::Resp;
18
19 type Err = E;
20
21 fn proc(req: &actix_web::HttpRequest, payload: &mut actix_web::dev::Payload) -> Self::Fut {
22 let task = T::proc(req, payload);
23 MapErrFut {
24 task,
25 _err: Default::default(),
26 }
27 }
28}
29
30#[pin_project::pin_project]
31pub struct MapErrFut<T: Treater + 'static, E: From<T::Err>> {
32 #[pin]
33 task: T::Fut,
34 _err: PhantomData<E>,
35}
36
37impl<T: Treater + 'static, E: From<T::Err>> Future for MapErrFut<T, E> {
38 type Output = Result<T::Resp, E>;
39
40 fn poll(self: std::pin::Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> Poll<Self::Output> {
41 let this = self.project();
42 let task = this.task;
43
44 pin_mut!(task);
45
46 match task.poll(cx) {
47 Poll::Ready(r) => match r {
48 Ok(data) => Poll::Ready(Ok(data)),
49 Err(err) => Poll::Ready(Err(E::from(err))),
50 },
51 Poll::Pending => Poll::Pending,
52 }
53 }
54}