use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};
use std::time::Duration;
use crate::timer::delay::Delay;
pub struct Timeout<F> {
future: F,
delay: Delay,
}
impl<F> Timeout<F>
where
F: Future,
{
pub(super) fn new(future: F, duration: Duration) -> Self {
Self {
future,
delay: Delay::new(duration),
}
}
}
impl<F> Future for Timeout<F>
where
F: Future,
{
type Output = Result<F::Output, TimeoutError>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = unsafe { self.get_unchecked_mut() };
let future = unsafe { Pin::new_unchecked(&mut this.future) };
if let Poll::Ready(output) = future.poll(cx) {
return Poll::Ready(Ok(output));
}
if let Poll::Ready(()) = Pin::new(&mut this.delay).poll(cx) {
return Poll::Ready(Err(TimeoutError));
}
Poll::Pending
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct TimeoutError;
impl std::fmt::Display for TimeoutError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str("operation timed out")
}
}
impl std::error::Error for TimeoutError {}