use std::future::IntoFuture;
use super::{
TaskResult,
cancel_result::CancelResult,
task_handle::TaskHandle,
task_handle_future::TaskHandleFuture,
task_result_handle::TaskResultHandle,
task_status::TaskStatus,
tracked_task_handle::TrackedTaskHandle,
try_get::TryGet,
};
use crate::hook::TaskId;
pub struct TrackedTask<R, E> {
handle: TaskHandle<R, E>,
}
impl<R, E> TrackedTask<R, E> {
#[inline]
pub(crate) const fn new(handle: TaskHandle<R, E>) -> Self {
Self { handle }
}
#[inline]
pub fn get(self) -> TaskResult<R, E>
where
R: Send,
E: Send,
{
<Self as TaskResultHandle<R, E>>::get(self)
}
#[inline]
pub fn try_get(self) -> TryGet<Self, R, E>
where
R: Send,
E: Send,
{
<Self as TaskResultHandle<R, E>>::try_get(self)
}
#[inline]
pub fn is_done(&self) -> bool
where
R: Send,
E: Send,
{
<Self as TaskResultHandle<R, E>>::is_done(self)
}
#[inline]
pub fn status(&self) -> TaskStatus {
self.handle.state.status()
}
#[inline]
pub fn task_id(&self) -> TaskId {
self.handle.task_id()
}
#[inline]
pub(crate) fn accept(&self) {
self.handle.accept();
}
#[inline]
pub fn cancel(&self) -> CancelResult {
self.cancel_inner()
}
#[inline]
fn cancel_inner(&self) -> CancelResult {
if self.handle.state.try_cancel_pending() {
return CancelResult::Cancelled;
}
match self.status() {
TaskStatus::Pending => CancelResult::Unsupported,
TaskStatus::Running => CancelResult::AlreadyRunning,
_ => CancelResult::AlreadyFinished,
}
}
}
impl<R, E> TaskResultHandle<R, E> for TrackedTask<R, E>
where
R: Send,
E: Send,
{
#[inline]
fn is_done(&self) -> bool {
self.status().is_done()
}
#[inline]
fn get(self) -> TaskResult<R, E> {
self.handle.get()
}
#[inline]
fn try_get(self) -> TryGet<Self, R, E> {
let Self { handle } = self;
match handle.try_get() {
TryGet::Ready(result) => TryGet::Ready(result),
TryGet::Pending(handle) => TryGet::Pending(Self { handle }),
}
}
}
impl<R, E> TrackedTaskHandle<R, E> for TrackedTask<R, E>
where
R: Send,
E: Send,
{
#[inline]
fn status(&self) -> TaskStatus {
self.handle.state.status()
}
#[inline]
fn cancel(&self) -> CancelResult {
self.cancel_inner()
}
}
impl<R, E> IntoFuture for TrackedTask<R, E> {
type Output = TaskResult<R, E>;
type IntoFuture = TaskHandleFuture<R, E>;
#[inline]
fn into_future(self) -> Self::IntoFuture {
self.handle.into_future()
}
}