use crate::prelude::*;
use crate::string::SharedString;
use crate::task;
pub type Index = usize;
#[derive(Deref, DerefMut)]
pub struct TryJoin<T, E> {
#[deref]
#[deref_mut]
join: task::Join<Result<T, E>>,
}
impl<T, E> TryJoin<T, E>
where
T: Send + 'static,
E: From<task::Panic> + Send + 'static,
{
pub fn new() -> Self {
Self { join: task::Join::new() }
}
pub fn add(&mut self, task: impl task::Start<Result<T, E>>) -> Index {
self.join.add(task)
}
pub fn add_as(
&mut self,
name: impl Into<SharedString>,
task: impl task::Start<Result<T, E>>,
) -> Index {
self.join.add_as(name, task)
}
pub async fn next(&mut self) -> Option<StoppedTask<T, E>> {
let task = self.join.next().await?;
Some(StoppedTask {
index: task.index,
name: task.name,
result: task.result.map_err(E::from).and_then(|res| res),
})
}
pub async fn try_next(&mut self) -> Option<Result<FinishedTask<T>, FailedTask<E>>> {
let task = self.next().await?;
Some(match task.result {
Ok(output) => Ok(FinishedTask { index: task.index, name: task.name, output }),
Err(error) => Err(FailedTask { index: task.index, name: task.name, error }),
})
}
pub async fn drain(&mut self) {
self.join.drain().await
}
pub async fn try_drain(&mut self) -> Result<(), FailedTask<E>> {
while self.try_next().await.transpose()?.is_some() {}
Ok(())
}
}
impl<T, E> Default for TryJoin<T, E>
where
T: Send + 'static,
E: From<Panic> + Send + 'static,
{
fn default() -> Self {
Self::new()
}
}
#[derive(Debug)]
pub struct StoppedTask<T, E> {
pub index: Index,
pub name: SharedString,
pub result: Result<T, E>,
}
#[derive(Debug)]
pub struct FinishedTask<T> {
pub index: Index,
pub name: SharedString,
pub output: T,
}
#[derive(Debug)]
pub struct FailedTask<E> {
pub index: Index,
pub name: SharedString,
pub error: E,
}
impl<E> Display for FailedTask<E>
where
E: Display,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.name.as_str() {
"" => write!(f, "Task #{} ", self.index)?,
name => write!(f, "Task `{}`", name)?,
}
write!(f, "failed. {}", self.error)
}
}
impl<E> Error for FailedTask<E> where E: Debug + Display {}