use std::sync::Arc;
struct StringError(String);
impl std::fmt::Display for StringError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.fmt(f)
}
}
impl std::fmt::Debug for StringError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.fmt(f)
}
}
impl std::error::Error for StringError {}
#[derive(Debug, Clone, Default)]
pub enum TaskStatus<T> {
#[default]
Idle,
Pending,
Resolved(T),
Aborted,
Error(Arc<dyn std::error::Error + Send + Sync>),
}
impl<T> TaskStatus<T> {
pub fn is_idle(&self) -> bool {
matches!(self, TaskStatus::Idle)
}
pub fn is_pending(&self) -> bool {
matches!(self, TaskStatus::Pending)
}
pub fn is_resolved(&self) -> bool {
matches!(self, TaskStatus::Resolved(_))
}
pub fn is_aborted(&self) -> bool {
matches!(self, TaskStatus::Aborted)
}
pub fn is_error(&self) -> bool {
matches!(self, TaskStatus::Error(_))
}
pub fn resolved(&self) -> Option<&T> {
match self {
TaskStatus::Resolved(v) => Some(v),
_ => None,
}
}
pub fn error(&self) -> Option<&(dyn std::error::Error + Send + Sync)> {
match self {
TaskStatus::Error(err) => Some(err.as_ref()),
_ => None,
}
}
}
impl<T> PartialEq for TaskStatus<T>
where
T: PartialEq,
{
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(TaskStatus::Resolved(a), TaskStatus::Resolved(b)) => a == b,
(
TaskStatus::Idle | TaskStatus::Pending | TaskStatus::Aborted,
TaskStatus::Idle | TaskStatus::Pending | TaskStatus::Aborted,
) => true,
(TaskStatus::Error(a), TaskStatus::Error(b)) => a.to_string() == b.to_string(),
_ => false,
}
}
}
impl<T> Eq for TaskStatus<T> where T: Eq {}
impl<T> From<String> for TaskStatus<T> {
fn from(msg: String) -> Self {
TaskStatus::Error(Arc::new(StringError(msg)))
}
}