use
{
crate :: { SpawnHandle, LocalSpawnHandle, JoinHandle, BlockingHandle } ,
std :: { rc::Rc, future::Future } ,
tokio :: { task::LocalSet, runtime::{ Runtime } } ,
futures_task :: { FutureObj, LocalFutureObj, Spawn, LocalSpawn, SpawnError } ,
};
#[ derive( Debug, Clone ) ]
#[ cfg_attr( nightly, doc(cfg( feature = "tokio_ct" )) ) ]
pub struct TokioCt
{
pub(crate) exec : Rc< Runtime > ,
pub(crate) local: Rc< LocalSet > ,
}
impl TokioCt
{
pub fn block_on<F: Future>( &self, f: F ) -> F::Output
{
self.exec.block_on( self.local.run_until( f ) )
}
}
impl Spawn for TokioCt
{
fn spawn_obj( &self, future: FutureObj<'static, ()> ) -> Result<(), SpawnError>
{
let _ = self.local.spawn_local( future );
Ok(())
}
}
impl LocalSpawn for TokioCt
{
fn spawn_local_obj( &self, future: LocalFutureObj<'static, ()> ) -> Result<(), SpawnError>
{
let _ = self.local.spawn_local( future );
Ok(())
}
}
impl<Out: 'static + Send> SpawnHandle<Out> for TokioCt
{
fn spawn_handle_obj( &self, future: FutureObj<'static, Out> ) -> Result<JoinHandle<Out>, SpawnError>
{
let handle = self.exec.spawn( future );
Ok( JoinHandle::tokio(handle) )
}
}
impl<Out: 'static> LocalSpawnHandle<Out> for TokioCt
{
fn spawn_handle_local_obj( &self, future: LocalFutureObj<'static, Out> ) -> Result<JoinHandle<Out>, SpawnError>
{
let handle = self.local.spawn_local( future );
Ok( JoinHandle::tokio(handle) )
}
}
#[ cfg(all( feature = "timer", not(feature="tokio_timer" )) ) ]
#[ cfg_attr( nightly, doc(cfg(all( feature = "timer", feature = "tokio_ct" ))) ) ]
impl crate::Timer for TokioCt
{
fn sleep( &self, dur: std::time::Duration ) -> futures_core::future::BoxFuture<'static, ()>
{
Box::pin( futures_timer::Delay::new(dur) )
}
}
#[ cfg( feature = "tokio_timer" ) ]
#[ cfg_attr( nightly, doc(cfg(all( feature = "tokio_timer", feature = "tokio_ct" ))) ) ]
impl crate::Timer for TokioCt
{
fn sleep( &self, dur: std::time::Duration ) -> futures_core::future::BoxFuture<'static, ()>
{
Box::pin( tokio::time::sleep(dur) )
}
}
#[ cfg( feature = "tokio_io" ) ]
#[ cfg_attr( nightly, doc(cfg( feature = "tokio_io" )) ) ]
impl crate::TokioIo for TokioCt {}
impl crate::YieldNow for TokioCt {}
impl<R: Send + 'static> crate::SpawnBlocking<R> for TokioCt
{
fn spawn_blocking<F>( &self, f: F ) -> BlockingHandle<R>
where F: FnOnce() -> R + Send + 'static ,
{
let handle = self.exec.as_ref().spawn_blocking( f );
BlockingHandle::tokio( handle )
}
fn spawn_blocking_dyn( &self, f: Box< dyn FnOnce()->R + Send > ) -> BlockingHandle<R>
{
self.spawn_blocking( f )
}
}
#[ cfg(test) ]
mod tests
{
use super::*;
static_assertions::assert_not_impl_any!( TokioCt: Send, Sync );
}