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