use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};
use std::time::Duration;
use crate::Transport;
pub(crate) async fn with_timeout<T, F>(dur: Duration, fut: F) -> Option<F::Output>
where
T: Transport,
F: Future,
{
Race {
fut: Box::pin(fut),
sleep: Box::pin(T::sleep(dur)),
}
.await
}
struct Race<F: Future, S: Future<Output = ()>> {
fut: Pin<Box<F>>,
sleep: Pin<Box<S>>,
}
impl<F: Future, S: Future<Output = ()>> Future for Race<F, S> {
type Output = Option<F::Output>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
if let Poll::Ready(out) = self.fut.as_mut().poll(cx) {
return Poll::Ready(Some(out));
}
if self.sleep.as_mut().poll(cx).is_ready() {
return Poll::Ready(None);
}
Poll::Pending
}
}