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 pub struct Task(async_executor::Task); impl 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(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { // Safe because Task is pinned and contains async_executor::Task by value unsafe { self.map_unchecked_mut(|x| &mut x.0).poll(cx) } } }