use super::{DroppableFuture, Runtime};
use futures_lite::Stream;
use std::{
future::Future,
pin::Pin,
task::{Context, Poll},
time::Duration,
};
pub trait RuntimeTrait: Into<Runtime> + Clone + Send + Sync + 'static {
fn spawn<Fut>(
&self,
fut: Fut,
) -> DroppableFuture<impl Future<Output = Option<Fut::Output>> + Send + 'static>
where
Fut: Future + Send + 'static,
Fut::Output: Send + 'static;
fn spawn_detached<Fut>(&self, fut: Fut)
where
Fut: Future<Output = ()> + Send + 'static,
{
drop(self.spawn(fut));
}
fn delay(&self, duration: Duration) -> impl Future<Output = ()> + Send;
fn interval(&self, period: Duration) -> impl Stream<Item = ()> + Send + 'static;
fn block_on<Fut>(&self, fut: Fut) -> Fut::Output
where
Fut: Future;
fn timeout<'runtime, 'fut, Fut>(
&'runtime self,
duration: Duration,
fut: Fut,
) -> impl Future<Output = Option<Fut::Output>> + Send + 'fut
where
Fut: Future + Send + 'fut,
Fut::Output: Send + 'static,
'runtime: 'fut,
{
Timeout {
fut,
delay: self.delay(duration),
}
}
fn hook_signals(
&self,
signals: impl IntoIterator<Item = i32>,
) -> impl Stream<Item = i32> + Send + 'static {
let _ = signals;
futures_lite::stream::empty()
}
}
pin_project_lite::pin_project! {
struct Timeout<Fut, Delay> {
#[pin]
fut: Fut,
#[pin]
delay: Delay,
}
}
impl<Fut: Future, Delay: Future<Output = ()>> Future for Timeout<Fut, Delay> {
type Output = Option<Fut::Output>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.project();
if let Poll::Ready(output) = this.fut.poll(cx) {
return Poll::Ready(Some(output));
}
this.delay.poll(cx).map(|()| None)
}
}