request_pretreat/prefabs/
error_mapping.rs

1use 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}