use super::Runtime;
use futures_01::future::{self as future_01, Future as Future01};
use futures_util::{compat::Future01CompatExt, FutureExt};
use std::future::Future;
use tokio_executor_01 as executor_01;
#[derive(Debug)]
#[cfg_attr(docsrs, doc(cfg(feature = "rt-current-thread")))]
pub struct TaskExecutor {
_p: (),
}
impl TaskExecutor {
pub fn current() -> TaskExecutor {
TaskExecutor { _p: () }
}
pub fn spawn_local(
&mut self,
future: impl Future01<Item = (), Error = ()> + 'static,
) -> Result<(), executor_01::SpawnError> {
self.spawn_local_std(future.compat().map(|_| ()))
}
pub fn spawn_local_std(
&mut self,
future: impl Future<Output = ()> + 'static,
) -> Result<(), executor_01::SpawnError> {
if let Some(idle) = Runtime::reserve_idle() {
tokio_02::task::spawn_local(idle.with(future));
Ok(())
} else {
Err(executor_01::SpawnError::shutdown())
}
}
pub fn spawn_handle<T: 'static, E: 'static>(
&mut self,
future: impl Future01<Item = T, Error = E> + 'static,
) -> tokio_02::task::JoinHandle<Result<T, E>> {
self.spawn_handle_std(future.compat())
}
pub fn spawn_handle_std<T: 'static>(
&mut self,
future: impl Future<Output = T> + 'static,
) -> tokio_02::task::JoinHandle<T> {
tokio_02::task::spawn_local(future)
}
}
impl<T> future_01::Executor<T> for TaskExecutor
where
T: Future01<Item = (), Error = ()> + 'static,
{
fn execute(&self, future: T) -> Result<(), future_01::ExecuteError<T>> {
if let Some(idle) = Runtime::reserve_idle() {
tokio_02::task::spawn_local(idle.with(future.compat()));
Ok(())
} else {
Err(future_01::ExecuteError::new(
future_01::ExecuteErrorKind::Shutdown,
future,
))
}
}
}
impl executor_01::Executor for TaskExecutor {
fn spawn(
&mut self,
future: Box<dyn Future01<Item = (), Error = ()> + Send>,
) -> Result<(), executor_01::SpawnError> {
self.spawn_local(future)
}
fn status(&self) -> Result<(), executor_01::SpawnError> {
if Runtime::is_current() {
Ok(())
} else {
Err(executor_01::SpawnError::shutdown())
}
}
}
impl<F> executor_01::TypedExecutor<F> for TaskExecutor
where
F: Future01<Item = (), Error = ()> + 'static,
{
fn spawn(&mut self, future: F) -> Result<(), executor_01::SpawnError> {
self.spawn_local(Box::new(future))
}
fn status(&self) -> Result<(), executor_01::SpawnError> {
executor_01::Executor::status(self)
}
}