use std::sync::Arc;
use qubit_function::Callable;
use super::{
TaskResult,
task_runner::TaskRunner,
task_state::TaskState,
};
pub struct RunningTaskSlot<R, E> {
state: Option<Arc<TaskState<R, E>>>,
}
impl<R, E> RunningTaskSlot<R, E> {
#[inline]
pub(crate) fn new(state: Arc<TaskState<R, E>>) -> Self {
Self { state: Some(state) }
}
#[inline]
fn state(&self) -> &TaskState<R, E> {
self.state
.as_deref()
.expect("running task slot state should be present")
}
#[inline]
pub fn complete(mut self, result: TaskResult<R, E>) -> bool {
let completed = self
.state()
.try_complete(result, self.state().is_accepted());
if completed {
self.state.take();
}
completed
}
#[inline]
pub fn run<C>(self, task: C) -> bool
where
C: Callable<R, E>,
{
self.complete(TaskRunner::new(task).call())
}
}
impl<R, E> Drop for RunningTaskSlot<R, E> {
#[inline]
fn drop(&mut self) {
if let Some(state) = &self.state {
let _ignored = state.try_drop_unfinished(state.is_accepted());
}
}
}