|
26 | 26 | //! # Ok(()) }) }
|
27 | 27 | //! ```
|
28 | 28 |
|
29 |
| -use std::error::Error; |
30 |
| -use std::fmt; |
31 |
| -use std::pin::Pin; |
32 |
| -use std::time::Duration; |
| 29 | +pub use timeout::{Timeout, TimeoutError}; |
33 | 30 |
|
34 |
| -use cfg_if::cfg_if; |
35 |
| -use futures_timer::Delay; |
36 |
| -use pin_utils::unsafe_pinned; |
37 |
| - |
38 |
| -use crate::future::Future; |
39 |
| -use crate::io; |
40 |
| -use crate::task::{Context, Poll}; |
41 |
| - |
42 |
| -cfg_if! { |
43 |
| - if #[cfg(feature = "docs")] { |
44 |
| - #[doc(hidden)] |
45 |
| - pub struct ImplFuture<T>(std::marker::PhantomData<T>); |
46 |
| - |
47 |
| - macro_rules! ret { |
48 |
| - ($f:tt, $o:ty) => (ImplFuture<$o>); |
49 |
| - } |
50 |
| - } else { |
51 |
| - macro_rules! ret { |
52 |
| - ($f:tt, $o:ty) => ($f<Self>); |
53 |
| - } |
54 |
| - } |
55 |
| -} |
56 |
| - |
57 |
| -/// An error returned when a future times out. |
58 |
| -#[derive(Clone, Copy, Debug, Eq, PartialEq)] |
59 |
| -pub struct TimeoutError; |
60 |
| - |
61 |
| -impl Error for TimeoutError {} |
62 |
| - |
63 |
| -impl fmt::Display for TimeoutError { |
64 |
| - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
65 |
| - "future has timed out".fmt(f) |
66 |
| - } |
67 |
| -} |
68 |
| - |
69 |
| -impl From<TimeoutError> for io::Error { |
70 |
| - fn from(_: TimeoutError) -> io::Error { |
71 |
| - io::Error::new(io::ErrorKind::TimedOut, "future has timed out") |
72 |
| - } |
73 |
| -} |
74 |
| - |
75 |
| -/// An extension trait that configures timeouts for futures. |
76 |
| -pub trait Timeout: Future + Sized { |
77 |
| - /// Awaits a future to completion or times out after a duration of time. |
78 |
| - /// |
79 |
| - /// # Examples |
80 |
| - /// |
81 |
| - /// ```no_run |
82 |
| - /// # #![feature(async_await)] |
83 |
| - /// # fn main() -> std::io::Result<()> { async_std::task::block_on(async { |
84 |
| - /// # |
85 |
| - /// use async_std::{io, prelude::*}; |
86 |
| - /// use std::time::Duration; |
87 |
| - /// |
88 |
| - /// let stdin = io::stdin(); |
89 |
| - /// let mut line = String::new(); |
90 |
| - /// |
91 |
| - /// let n = stdin |
92 |
| - /// .read_line(&mut line) |
93 |
| - /// .timeout(Duration::from_secs(5)) |
94 |
| - /// .await??; |
95 |
| - /// # |
96 |
| - /// # Ok(()) }) } |
97 |
| - /// ``` |
98 |
| - fn timeout(self, dur: Duration) -> ret!(TimeoutFuture, Result<Self::Output, TimeoutError>) { |
99 |
| - TimeoutFuture { |
100 |
| - future: self, |
101 |
| - delay: Delay::new(dur), |
102 |
| - } |
103 |
| - } |
104 |
| -} |
105 |
| - |
106 |
| -/// A future that times out after a duration of time. |
107 |
| -#[doc(hidden)] |
108 |
| -#[allow(missing_debug_implementations)] |
109 |
| -pub struct TimeoutFuture<F> { |
110 |
| - future: F, |
111 |
| - delay: Delay, |
112 |
| -} |
113 |
| - |
114 |
| -impl<F> TimeoutFuture<F> { |
115 |
| - unsafe_pinned!(future: F); |
116 |
| - unsafe_pinned!(delay: Delay); |
117 |
| -} |
118 |
| - |
119 |
| -impl<F: Future> Future for TimeoutFuture<F> { |
120 |
| - type Output = Result<F::Output, TimeoutError>; |
121 |
| - |
122 |
| - fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |
123 |
| - match self.as_mut().future().poll(cx) { |
124 |
| - Poll::Ready(v) => Poll::Ready(Ok(v)), |
125 |
| - Poll::Pending => match self.delay().poll(cx) { |
126 |
| - Poll::Ready(_) => Poll::Ready(Err(TimeoutError)), |
127 |
| - Poll::Pending => Poll::Pending, |
128 |
| - }, |
129 |
| - } |
130 |
| - } |
131 |
| -} |
132 |
| - |
133 |
| -impl<F: Future> Timeout for F {} |
| 31 | +mod timeout; |
0 commit comments