request_pretreat/prefabs/
resp_result.rs

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