1use async_trait::async_trait;
2use std::{
3 future::Future,
4 pin::Pin,
5 task::{Context, Poll},
6};
7
8#[derive(Debug)]
10pub struct Task<I: TaskImpl>(I);
11
12impl<I: TaskImpl> Task<I> {
13 pub async fn cancel(&mut self) -> Option<<Self as Future>::Output> {
15 self.0.cancel().await
16 }
17}
18
19impl<I: TaskImpl> From<I> for Task<I> {
20 fn from(task_impl: I) -> Self {
21 Self(task_impl)
22 }
23}
24
25impl<I: TaskImpl> Future for Task<I> {
26 type Output = <I as Future>::Output;
27
28 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
29 Pin::new(&mut self.0).poll(cx)
30 }
31}
32
33impl<I: TaskImpl> Drop for Task<I> {
34 fn drop(&mut self) {
35 self.0.detach();
36 }
37}
38
39#[async_trait]
41pub trait TaskImpl: Future + Send + Unpin + 'static {
42 async fn cancel(&mut self) -> Option<<Self as Future>::Output> {
47 None
48 }
49
50 fn detach(&mut self)
55 where
56 Self: Sized,
57 {
58 }
59}