diff --git a/examples/async-echo.rs b/examples/async-echo.rs index 24d91f6..e30ca27 100644 --- a/examples/async-echo.rs +++ b/examples/async-echo.rs @@ -7,7 +7,7 @@ async fn echo_to(port: u16) -> Result<(), Box> { let stream = TcpStream::connect(sockaddr)?; stream.set_nonblocking(true)?; - let mut stream = Async::new(stream); + let mut stream = Async::new(stream)?; println!("Connected"); diff --git a/src/time.rs b/src/time.rs index 858b306..862a2e5 100644 --- a/src/time.rs +++ b/src/time.rs @@ -20,6 +20,18 @@ pub fn interval_at(instant: Instant, duration: Duration) -> Interval { } } +pub fn timeout(duration: Duration, future: F) -> Timeout { + Timeout { + timer: Timer::new(duration), + future, + } +} + +pub struct Timeout { + timer: Timer, + future: F, +} + pub struct Interval { next: Instant, duration: Duration, @@ -46,3 +58,23 @@ impl Interval { Timer::new(duration) } } + +impl std::future::Future for Timeout +where + F: std::future::Future + Unpin, +{ + type Output = std::io::Result; + + fn poll( + self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll { + let this = self.get_mut(); + + if std::pin::Pin::new(&mut this.timer).poll(cx).is_ready() { + return std::task::Poll::Ready(Err(std::io::ErrorKind::TimedOut.into())); + } + + std::pin::Pin::new(&mut this.future).poll(cx).map(Ok) + } +}