use crate::helpers::{leak, spawn_timeboxed};
use std::future::{Future, IntoFuture};
use std::time::Duration;
use tokio::task::JoinHandle;
use tokio::time::error::Elapsed;
pub trait Leak {
fn leak(self) -> &'static mut Self;
}
impl<T> Leak for T {
fn leak(self) -> &'static mut T {
leak(self)
}
}
#[allow(async_fn_in_trait)]
pub trait Timeboxed: IntoFuture + Sized {
async fn timeboxed(self) -> Result<Self::Output, Elapsed> {
self.execute_with_deadline(Duration::from_millis(200)).await
}
async fn execute_with_deadline(self, timeout: Duration) -> Result<Self::Output, Elapsed> {
tokio::time::timeout(timeout, self).await
}
}
impl<T> Timeboxed for T where T: IntoFuture + Sized {}
pub trait ElapsedExt {
fn has_elapsed(&self) -> bool;
}
impl<T> ElapsedExt for Result<T, Elapsed> {
fn has_elapsed(&self) -> bool {
self.is_err()
}
}
#[allow(async_fn_in_trait)]
pub trait Spawnable: Future + Sized + Send + 'static {
fn spawn(self) -> JoinHandle<Self::Output>
where
<Self as Future>::Output: Send + 'static,
{
tokio::spawn(self)
}
}
impl<T> Spawnable for T where T: Future + Sized + Send + 'static {}
pub trait TimeboxedSpawnable: Timeboxed + Spawnable {
fn spawn_timeboxed(self) -> JoinHandle<Result<<Self as Future>::Output, Elapsed>>
where
<Self as Future>::Output: Send,
{
spawn_timeboxed(self)
}
}
impl<T> TimeboxedSpawnable for T where T: Spawnable + Future + Send {}