use alloc::boxed::Box;
use core::future::Future;
use core::pin::Pin;
use core::task::Poll;
use core::time::Duration;
#[cfg(feature = "tokio-runtime")]
pub mod tokio;
pub trait Executor: Send + Sync + 'static {
fn spawn(&self, future: Pin<Box<dyn Future<Output = ()> + Send>>);
}
pub trait Timer: Send + Sync + 'static {
fn delay<'a>(&'a self, duration: Duration) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>>;
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Elapsed;
pub(crate) async fn with_timeout<F: Future>(
timer: &dyn Timer,
duration: Duration,
fut: F,
) -> Result<F::Output, Elapsed> {
let mut fut = core::pin::pin!(fut);
let mut delay = timer.delay(duration);
core::future::poll_fn(move |cx| {
if let Poll::Ready(value) = fut.as_mut().poll(cx) {
return Poll::Ready(Ok(value));
}
if let Poll::Ready(()) = delay.as_mut().poll(cx) {
return Poll::Ready(Err(Elapsed));
}
Poll::Pending
})
.await
}