use std::{ future::Future, pin::Pin, task::{Context, Poll}, }; /// Wraps `async_executor::Task`, a spawned future. /// /// Tasks are also futures themselves and yield the output of the spawned future. /// /// When a task is dropped, its gets canceled and won't be polled again. To cancel a task a bit /// more gracefully and wait until it stops running, use the [`cancel()`][Task::cancel()] method. /// /// Tasks that panic get immediately canceled. Awaiting a canceled task also causes a panic. /// Wraps async_executor::Task #[derive(Debug)] pub struct Task(async_executor::Task); impl Task { /// Creates a new task from a given async_executor::Task pub fn new(task: async_executor::Task) -> Self { Self(task) } /// Detaches the task to let it keep running in the background. See `async_executor::Task::detach` pub fn detach(self) { self.0.detach(); } /// Cancels the task and waits for it to stop running. /// /// Returns the task's output if it was completed just before it got canceled, or [`None`] if /// it didn't complete. /// /// While it's possible to simply drop the [`Task`] to cancel it, this is a cleaner way of /// canceling because it also waits for the task to stop running. /// /// See `async_executor::Task::cancel` pub async fn cancel(self) -> Option { self.0.cancel().await } } impl Future for Task { type Output = T; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { Pin::new(&mut self.0).poll(cx) } }