async_rs/traits/
executor.rs

1//! A collection of traits to define a common interface across executors
2
3use async_trait::async_trait;
4use std::{future::Future, ops::Deref};
5
6/// A common interface for spawning futures on top of an executor
7pub trait Executor {
8    /// Block on a future until completion
9    fn block_on<T, F: Future<Output = T>>(&self, f: F) -> T
10    where
11        Self: Sized;
12
13    /// Spawn a future and return a handle to track its completion.
14    fn spawn<T: Send + 'static, F: Future<Output = T> + Send + 'static>(
15        &self,
16        f: F,
17    ) -> impl Task<T> + 'static
18    where
19        Self: Sized;
20
21    /// Convert a blocking task into a future, spawning it on a decicated thread pool
22    fn spawn_blocking<T: Send + 'static, F: FnOnce() -> T + Send + 'static>(
23        &self,
24        f: F,
25    ) -> impl Task<T> + 'static
26    where
27        Self: Sized;
28}
29
30impl<E: Deref> Executor for E
31where
32    E::Target: Executor + Sized,
33{
34    fn block_on<T, F: Future<Output = T>>(&self, f: F) -> T {
35        self.deref().block_on(f)
36    }
37
38    fn spawn<T: Send + 'static, F: Future<Output = T> + Send + 'static>(
39        &self,
40        f: F,
41    ) -> impl Task<T> + 'static {
42        self.deref().spawn(f)
43    }
44
45    fn spawn_blocking<T: Send + 'static, F: FnOnce() -> T + Send + 'static>(
46        &self,
47        f: F,
48    ) -> impl Task<T> + 'static {
49        self.deref().spawn_blocking(f)
50    }
51}
52
53/// A common interface to wait for a Task completion, let it run n the background or cancel it.
54#[async_trait]
55pub trait Task<T: Send + 'static>: Future<Output = T> + Send + 'static {
56    /// Cancels the task and waits for it to stop running.
57    ///
58    /// Returns the task's output if it was completed just before it got canceled, or None if it
59    /// didn't complete.
60    async fn cancel(&mut self) -> Option<T>;
61}