sui_http/middleware/callback/
future.rs1use super::ResponseBody;
5use super::ResponseHandler;
6use http::Response;
7use pin_project_lite::pin_project;
8use std::future::Future;
9use std::pin::Pin;
10use std::task::Context;
11use std::task::Poll;
12
13pin_project! {
14 pub struct ResponseFuture<F, ResponseHandler> {
18 #[pin]
19 pub(crate) inner: F,
20 pub(crate) handler: Option<ResponseHandler>,
21 }
22}
23
24impl<Fut, B, E, ResponseHandlerT> Future for ResponseFuture<Fut, ResponseHandlerT>
25where
26 Fut: Future<Output = Result<Response<B>, E>>,
27 B: http_body::Body<Error: std::fmt::Display + 'static>,
28 E: std::fmt::Display + 'static,
29 ResponseHandlerT: ResponseHandler,
30{
31 type Output = Result<Response<ResponseBody<B, ResponseHandlerT>>, E>;
32
33 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
34 let this = self.project();
35 let result = futures_core::ready!(this.inner.poll(cx));
36 let mut handler = this.handler.take().unwrap();
37
38 let result = match result {
39 Ok(response) => {
40 let (head, body) = response.into_parts();
41 handler.on_response(&head);
42 Ok(Response::from_parts(
43 head,
44 ResponseBody {
45 inner: body,
46 handler,
47 },
48 ))
49 }
50 Err(error) => {
51 handler.on_error(&error);
52 Err(error)
53 }
54 };
55
56 Poll::Ready(result)
57 }
58}