use crate::lib::{
alloc::{
fmt::{Debug, Formatter, Result},
sync::Arc,
},
core::future::Future,
};
use futures::future::{BoxFuture, FutureExt};
#[async_trait::async_trait]
pub trait Runtime: Clone + Send {
fn spawn<R>(&self, future: impl Future<Output = R> + Send + 'static)
where
R: Send + 'static;
async fn sleep(self, delay: u64);
async fn sleep_microseconds(self, delay: u64);
}
#[derive(Clone)]
pub(crate) struct RuntimeSupport {
spawner: Arc<dyn Fn(BoxFuture<'static, ()>) + Send + Sync>,
sleeper: Arc<dyn Fn(u64) -> BoxFuture<'static, ()> + Send + Sync>,
sleeper_microseconds: Arc<dyn Fn(u64) -> BoxFuture<'static, ()> + Send + Sync>,
}
impl RuntimeSupport {
pub fn new<R>(runtime: Arc<R>) -> Self
where
R: Runtime + Copy + Send + Sync + 'static,
{
let spawn_runtime = runtime.clone();
let sleep_runtime = runtime.clone();
let sleep_microseconds_runtime = runtime.clone();
Self {
sleeper: Arc::new(move |delay| sleep_runtime.sleep(delay).boxed()),
sleeper_microseconds: Arc::new(move |delay| {
sleep_microseconds_runtime.sleep_microseconds(delay).boxed()
}),
spawner: Arc::new(Box::new(move |future| {
spawn_runtime.spawn(future);
})),
}
}
}
#[async_trait::async_trait]
impl Runtime for RuntimeSupport {
fn spawn<R>(&self, future: impl Future<Output = R> + Send + 'static)
where
R: Send + 'static,
{
(self.spawner.clone())(
async move {
future.await;
}
.boxed(),
);
}
async fn sleep(self, delay: u64) {
(self.sleeper)(delay).await
}
async fn sleep_microseconds(self, delay: u64) {
(self.sleeper_microseconds)(delay).await
}
}
impl Debug for RuntimeSupport {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
write!(f, "RuntimeSupport {{}}")
}
}