1 | //! Future types |
2 | |
3 | use super::error::Elapsed; |
4 | use pin_project_lite::pin_project; |
5 | use std::{ |
6 | future::Future, |
7 | pin::Pin, |
8 | task::{Context, Poll}, |
9 | }; |
10 | use tokio::time::Sleep; |
11 | |
12 | pin_project! { |
13 | /// [`Timeout`] response future |
14 | /// |
15 | /// [`Timeout`]: crate::timeout::Timeout |
16 | #[derive (Debug)] |
17 | pub struct ResponseFuture<T> { |
18 | #[pin] |
19 | response: T, |
20 | #[pin] |
21 | sleep: Sleep, |
22 | } |
23 | } |
24 | |
25 | impl<T> ResponseFuture<T> { |
26 | pub(crate) fn new(response: T, sleep: Sleep) -> Self { |
27 | ResponseFuture { response, sleep } |
28 | } |
29 | } |
30 | |
31 | impl<F, T, E> Future for ResponseFuture<F> |
32 | where |
33 | F: Future<Output = Result<T, E>>, |
34 | E: Into<crate::BoxError>, |
35 | { |
36 | type Output = Result<T, crate::BoxError>; |
37 | |
38 | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |
39 | let this: Projection<'_, F> = self.project(); |
40 | |
41 | // First, try polling the future |
42 | match this.response.poll(cx) { |
43 | Poll::Ready(v: Result) => return Poll::Ready(v.map_err(op:Into::into)), |
44 | Poll::Pending => {} |
45 | } |
46 | |
47 | // Now check the sleep |
48 | match this.sleep.poll(cx) { |
49 | Poll::Pending => Poll::Pending, |
50 | Poll::Ready(_) => Poll::Ready(Err(Elapsed(()).into())), |
51 | } |
52 | } |
53 | } |
54 | |