use async_trait::async_trait;
use std::{
future::Future,
pin::Pin,
task::{Context, Poll},
};
#[derive(Debug)]
pub struct Task<I: TaskImpl>(I);
impl<I: TaskImpl> Task<I> {
pub async fn cancel(&mut self) -> Option<<Self as Future>::Output> {
self.0.cancel().await
}
}
impl<I: TaskImpl> From<I> for Task<I> {
fn from(task_impl: I) -> Self {
Self(task_impl)
}
}
impl<I: TaskImpl> Future for Task<I> {
type Output = <I as Future>::Output;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
Pin::new(&mut self.0).poll(cx)
}
}
impl<I: TaskImpl> Drop for Task<I> {
fn drop(&mut self) {
self.0.detach();
}
}
#[async_trait]
pub trait TaskImpl: Future + Send + Unpin + 'static {
async fn cancel(&mut self) -> Option<<Self as Future>::Output> {
None
}
fn detach(&mut self)
where
Self: Sized,
{
}
}