async_rs/traits/
executor.rs

1//! A collection of traits to define a common interface across executors
2
3use crate::util::{Task, TaskImpl};
4use std::{future::Future, ops::Deref};
5
6/// A common interface for spawning futures on top of an executor
7pub trait Executor {
8    /// The type representing the tasks the are returned when spawning a Future on the executor
9    type Task<T: Send + 'static>: TaskImpl<Output = T> + Send + 'static;
10
11    /// Block on a future until completion
12    fn block_on<T, F: Future<Output = T>>(&self, f: F) -> T
13    where
14        Self: Sized;
15
16    /// Spawn a future and return a handle to track its completion.
17    fn spawn<T: Send + 'static, F: Future<Output = T> + Send + 'static>(
18        &self,
19        f: F,
20    ) -> Task<Self::Task<T>>
21    where
22        Self: Sized;
23
24    /// Convert a blocking task into a future, spawning it on a decicated thread pool
25    fn spawn_blocking<T: Send + 'static, F: FnOnce() -> T + Send + 'static>(
26        &self,
27        f: F,
28    ) -> Task<Self::Task<T>>
29    where
30        Self: Sized;
31}
32
33impl<E: Deref> Executor for E
34where
35    E::Target: Executor + Sized,
36{
37    type Task<T: Send + 'static> = <E::Target as Executor>::Task<T>;
38
39    fn block_on<T, F: Future<Output = T>>(&self, f: F) -> T {
40        self.deref().block_on(f)
41    }
42
43    fn spawn<T: Send + 'static, F: Future<Output = T> + Send + 'static>(
44        &self,
45        f: F,
46    ) -> Task<Self::Task<T>> {
47        self.deref().spawn(f)
48    }
49
50    fn spawn_blocking<T: Send + 'static, F: FnOnce() -> T + Send + 'static>(
51        &self,
52        f: F,
53    ) -> Task<Self::Task<T>> {
54        self.deref().spawn_blocking(f)
55    }
56}