1 use super::{Compat, Future01CompatExt}; 2 use crate::{ 3 future::{FutureExt, TryFutureExt, UnitError}, 4 task::SpawnExt, 5 }; 6 use futures_01::future::{ExecuteError as ExecuteError01, Executor as Executor01}; 7 use futures_01::Future as Future01; 8 use futures_task::{FutureObj, Spawn as Spawn03, SpawnError as SpawnError03}; 9 10 /// A future that can run on a futures 0.1 11 /// [`Executor`](futures_01::future::Executor). 12 pub type Executor01Future = Compat<UnitError<FutureObj<'static, ()>>>; 13 14 /// Extension trait for futures 0.1 [`Executor`](futures_01::future::Executor). 15 pub trait Executor01CompatExt: Executor01<Executor01Future> + Clone + Send + 'static { 16 /// Converts a futures 0.1 [`Executor`](futures_01::future::Executor) into a 17 /// futures 0.3 [`Spawn`](futures_task::Spawn). 18 /// 19 /// ``` 20 /// use futures::task::SpawnExt; 21 /// use futures::future::{FutureExt, TryFutureExt}; 22 /// use futures_util::compat::Executor01CompatExt; 23 /// use tokio::executor::DefaultExecutor; 24 /// 25 /// # let (tx, rx) = futures::channel::oneshot::channel(); 26 /// 27 /// let spawner = DefaultExecutor::current().compat(); 28 /// let future03 = async move { 29 /// println!("Running on the pool"); 30 /// spawner.spawn(async { 31 /// println!("Spawned!"); 32 /// # tx.send(42).unwrap(); 33 /// }).unwrap(); 34 /// }; 35 /// 36 /// let future01 = future03.unit_error().boxed().compat(); 37 /// 38 /// tokio::run(future01); 39 /// # futures::executor::block_on(rx).unwrap(); 40 /// ``` compat(self) -> Executor01As03<Self> where Self: Sized41 fn compat(self) -> Executor01As03<Self> 42 where 43 Self: Sized; 44 } 45 46 impl<Ex> Executor01CompatExt for Ex 47 where 48 Ex: Executor01<Executor01Future> + Clone + Send + 'static, 49 { compat(self) -> Executor01As03<Self>50 fn compat(self) -> Executor01As03<Self> { 51 Executor01As03 { executor01: self } 52 } 53 } 54 55 /// Converts a futures 0.1 [`Executor`](futures_01::future::Executor) into a 56 /// futures 0.3 [`Spawn`](futures_task::Spawn). 57 #[derive(Debug, Clone)] 58 pub struct Executor01As03<Ex> { 59 executor01: Ex, 60 } 61 62 impl<Ex> Spawn03 for Executor01As03<Ex> 63 where 64 Ex: Executor01<Executor01Future> + Clone + Send + 'static, 65 { spawn_obj(&self, future: FutureObj<'static, ()>) -> Result<(), SpawnError03>66 fn spawn_obj(&self, future: FutureObj<'static, ()>) -> Result<(), SpawnError03> { 67 let future = future.unit_error().compat(); 68 69 self.executor01.execute(future).map_err(|_| SpawnError03::shutdown()) 70 } 71 } 72 73 #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058 74 impl<Sp, Fut> Executor01<Fut> for Compat<Sp> 75 where 76 for<'a> &'a Sp: Spawn03, 77 Fut: Future01<Item = (), Error = ()> + Send + 'static, 78 { execute(&self, future: Fut) -> Result<(), ExecuteError01<Fut>>79 fn execute(&self, future: Fut) -> Result<(), ExecuteError01<Fut>> { 80 (&self.inner) 81 .spawn(future.compat().map(|_| ())) 82 .expect("unable to spawn future from Compat executor"); 83 Ok(()) 84 } 85 } 86