use crate::async_error::AsyncError;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Eq, PartialEq, Default, Hash)]
#[cfg_attr(
feature = "serde",
derive(Serialize, Deserialize),
serde(rename_all = "camelCase")
)]
pub enum Async<T: Clone> {
#[default]
Uninitialized,
Loading { value: Option<T> },
Success { value: T },
Fail { error: AsyncError, value: Option<T> },
}
impl<T: Clone> Async<T> {
pub fn is_complete(&self) -> bool {
matches!(self, Async::Success { .. } | Async::Fail { .. })
}
pub fn should_load(&self) -> bool {
matches!(self, Async::Uninitialized | Async::Fail { .. })
}
pub fn is_incomplete(&self) -> bool {
matches!(self, Async::Uninitialized | Async::Loading { .. })
}
pub fn is_uninitialized(&self) -> bool {
matches!(self, Async::Uninitialized)
}
pub fn is_loading(&self) -> bool {
matches!(self, Async::Loading { .. })
}
pub fn is_success(&self) -> bool {
matches!(self, Async::Success { .. })
}
pub fn is_fail(&self) -> bool {
matches!(self, Async::Fail { .. })
}
pub fn is_fail_with_error(&self) -> bool {
if let Async::Fail { error, .. } = self {
error.is_error()
} else {
false
}
}
pub fn is_fail_with_none(&self) -> bool {
if let Async::Fail { error, .. } = self {
error.is_none()
} else {
false
}
}
pub fn is_fail_with_canceled(&self) -> bool {
if let Async::Fail { error, .. } = self {
error.is_cancelled()
} else {
false
}
}
pub fn is_fail_with_timeout(&self) -> bool {
if let Async::Fail { error, .. } = self {
error.is_timeout()
} else {
false
}
}
pub fn value(self) -> Option<T> {
match self {
Async::Uninitialized => None,
Async::Loading { value } => value,
Async::Success { value, .. } => Some(value),
Async::Fail { value, .. } => value,
}
}
pub fn value_ref(&self) -> Option<&T> {
match self {
Async::Loading { value: Some(value) } => Some(value),
Async::Success { value } => Some(value),
Async::Fail {
value: Some(value), ..
} => Some(value),
_ => None,
}
}
pub fn value_ref_clone(self: &Async<T>) -> Option<T> {
match self {
Async::Loading { value: Some(value) } => Some(value.clone()),
Async::Success { value } => Some(value.clone()),
Async::Fail {
value: Some(value), ..
} => Some(value.clone()),
_ => None,
}
}
pub fn set_retain_value(mut self, value: Option<T>) -> Self {
match self {
Async::Loading { .. } => {
self = Async::loading(value);
}
Async::Fail { error, .. } => {
self = Async::fail(error, value);
}
_ => {}
}
self
}
pub fn loading(value: Option<T>) -> Self {
Async::Loading { value }
}
pub fn success(value: T) -> Self {
Async::Success { value }
}
pub fn fail(error: AsyncError, value: Option<T>) -> Self {
Async::Fail { error, value }
}
pub fn fail_with_cancelled(value: Option<T>) -> Self {
Async::Fail {
error: AsyncError::Cancelled,
value,
}
}
pub fn fail_with_timeout(value: Option<T>) -> Self {
Async::Fail {
error: AsyncError::Timeout,
value,
}
}
pub fn fail_with_message(message: impl Into<String>, value: Option<T>) -> Self {
let error = AsyncError::error(message.into());
Async::Fail { error, value }
}
pub fn fail_with_none(value: Option<T>) -> Self {
Async::Fail {
error: AsyncError::None,
value,
}
}
}