sui_http/middleware/callback/
future.rs

1// Copyright (c) Mysten Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4use 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    /// Response future for [`Callback`].
15    ///
16    /// [`Callback`]: super::Callback
17    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}