Skip to main content

shrub_core/
tasks.rs

1//! Tasks the shell runs concurrently with itself.
2
3use std::pin::Pin;
4use std::task::{Context, Poll};
5
6use crate::error;
7
8/// A future that yields a task's output when it finishes.
9type TaskFuture<T> = Pin<Box<dyn Future<Output = Result<T, error::Error>> + Send + Sync>>;
10
11/// Tracks a task started on the shell's behalf. Awaiting it yields the task's
12/// output, or an error if the task couldn't run to completion (e.g., it
13/// panicked).
14///
15/// Dropping the handle doesn't stop the task.
16pub struct TaskHandle<T> {
17    future: TaskFuture<T>,
18}
19
20impl<T> TaskHandle<T> {
21    /// Tracks a task through a future that yields its output when it finishes.
22    ///
23    /// # Arguments
24    ///
25    /// * `future` - The future to await for the task's output.
26    pub(crate) fn from_future(
27        future: impl Future<Output = Result<T, error::Error>> + Send + Sync + 'static,
28    ) -> Self {
29        Self {
30            future: Box::pin(future),
31        }
32    }
33}
34
35impl<T> Future for TaskHandle<T> {
36    type Output = Result<T, error::Error>;
37
38    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
39        self.future.as_mut().poll(cx)
40    }
41}