use async_scoped::spawner::{Blocker, FuncSpawner, Spawner};
use futures::Future;
pub(crate) mod abort;
pub trait Runtime: 'static {
type ScopedSpawner: Spawner<()>
+ FuncSpawner<(), SpawnHandle = <Self::ScopedSpawner as Spawner<()>>::SpawnHandle>
+ Blocker
+ Default
+ Send
+ Sync
+ 'static;
type BlockingRunner: BlockingRunner;
}
pub trait BlockingRunner: 'static {
fn block_on<F: Future>(fut: F) -> F::Output;
}
#[cfg(feature = "tokio")]
#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
#[allow(missing_debug_implementations)]
pub enum Tokio {}
#[cfg(feature = "tokio")]
#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
pub mod tokio {
#![allow(missing_debug_implementations)]
use super::*;
impl Runtime for Tokio {
type ScopedSpawner = async_scoped::spawner::use_tokio::Tokio;
type BlockingRunner = TokioBlockingRunner;
}
pub struct TokioBlockingRunner;
impl BlockingRunner for TokioBlockingRunner {
fn block_on<F: Future>(fut: F) -> F::Output {
::tokio::runtime::Handle::current().block_on(fut)
}
}
}
#[cfg(feature = "async-std")]
#[cfg_attr(docsrs, doc(cfg(feature = "async-std")))]
#[allow(missing_debug_implementations)]
pub enum AsyncStd {}
#[cfg(feature = "async-std")]
#[cfg_attr(docsrs, doc(cfg(feature = "async-std")))]
pub mod async_std {
#![allow(missing_debug_implementations)]
use super::*;
impl Runtime for AsyncStd {
type ScopedSpawner = async_scoped::spawner::use_async_std::AsyncStd;
type BlockingRunner = AsyncStdBlockingRunner;
}
pub struct AsyncStdBlockingRunner;
impl BlockingRunner for AsyncStdBlockingRunner {
fn block_on<F: Future>(fut: F) -> F::Output {
::async_std::task::block_on(fut)
}
}
}
#[cfg(feature = "smol")]
#[cfg_attr(docsrs, doc(cfg(feature = "smol")))]
#[allow(missing_debug_implementations)]
pub enum Smol {}
#[cfg(feature = "smol")]
#[cfg_attr(docsrs, doc(cfg(feature = "smol")))]
pub mod smol {
#![allow(missing_debug_implementations)]
use super::*;
impl Runtime for Smol {
type ScopedSpawner = SmolScopedSpawner;
type BlockingRunner = SmolBlockingRunner;
}
#[derive(Default)]
#[allow(missing_debug_implementations)]
pub struct SmolScopedSpawner;
unsafe impl<T: Send + 'static> Spawner<T> for SmolScopedSpawner {
type FutureOutput = T;
type SpawnHandle = ::smol::Task<T>;
fn spawn<F: Future<Output = T> + Send + 'static>(&self, f: F) -> Self::SpawnHandle {
::smol::spawn(f)
}
}
unsafe impl<T: Send + 'static> FuncSpawner<T> for SmolScopedSpawner {
type FutureOutput = T;
type SpawnHandle = ::smol::Task<T>;
fn spawn_func<F: FnOnce() -> T + Send + 'static>(&self, f: F) -> Self::SpawnHandle {
::smol::unblock(f)
}
}
unsafe impl Blocker for SmolScopedSpawner {
fn block_on<T, F: Future<Output = T>>(&self, f: F) -> T {
::smol::block_on(f)
}
}
pub struct SmolBlockingRunner;
impl BlockingRunner for SmolBlockingRunner {
fn block_on<F: Future>(fut: F) -> F::Output {
::smol::block_on(fut)
}
}
}