futures_time/future/
timeout.rs1use crate::utils::timeout_err;
2
3use std::future::Future;
4use std::io;
5use std::pin::Pin;
6use std::task::{Context, Poll};
7
8use pin_project_lite::pin_project;
9
10pin_project! {
11 #[must_use = "futures do nothing unless polled or .awaited"]
19 pub struct Timeout<F, D> {
20 #[pin]
21 future: F,
22 #[pin]
23 deadline: D,
24 completed: bool,
25 }
26}
27
28impl<F, D> Timeout<F, D> {
29 pub(super) fn new(future: F, deadline: D) -> Self {
30 Self {
31 future,
32 deadline,
33 completed: false,
34 }
35 }
36}
37
38impl<F: Future, D: Future> Future for Timeout<F, D> {
39 type Output = io::Result<F::Output>;
40
41 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
42 let this = self.project();
43
44 assert!(!*this.completed, "future polled after completing");
45
46 match this.future.poll(cx) {
47 Poll::Ready(v) => {
48 *this.completed = true;
49 Poll::Ready(Ok(v))
50 }
51 Poll::Pending => match this.deadline.poll(cx) {
52 Poll::Ready(_) => {
53 *this.completed = true;
54 Poll::Ready(Err(timeout_err("future timed out")))
55 }
56 Poll::Pending => Poll::Pending,
57 },
58 }
59 }
60}