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>(&self, f: impl Future<Output = T> + Send + 'static) -> impl Task<T>
15    where
16        Self: Sized;
17
18    /// Convert a blocking task into a future, spawning it on a decicated thread pool
19    fn spawn_blocking<F: FnOnce() -> T + Send + 'static, T: Send + 'static>(
20        &self,
21        f: F,
22    ) -> impl Task<T>
23    where
24        Self: Sized;
25}
26
27impl<E: Deref> Executor for E
28where
29    E::Target: Executor + Sized,
30{
31    fn block_on<T, F: Future<Output = T>>(&self, f: F) -> T {
32        self.deref().block_on(f)
33    }
34
35    fn spawn<T: Send + 'static>(
36        &self,
37        f: impl Future<Output = T> + Send + 'static,
38    ) -> impl Task<T> {
39        self.deref().spawn(f)
40    }
41
42    fn spawn_blocking<F: FnOnce() -> T + Send + 'static, T: Send + 'static>(
43        &self,
44        f: F,
45    ) -> impl Task<T> {
46        self.deref().spawn_blocking(f)
47    }
48}
49
50/// A common interface to wait for a Task completion, let it run n the background or cancel it.
51#[async_trait(?Send)]
52pub trait Task<T>: Future<Output = T> + Send {
53    /// Cancels the task and waits for it to stop running.
54    ///
55    /// Returns the task's output if it was completed just before it got canceled, or None if it
56    /// didn't complete.
57    async fn cancel(&mut self) -> Option<T>;
58}