use serde::de::Unexpected;
use serde::{self, Deserialize, Deserializer, Serialize, Serializer};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum StatusCode {
Waiting,
Queued,
Started,
InProgress,
Summarized,
Finished,
Faulty,
Unknown,
}
impl StatusCode {
pub fn is_working(self) -> bool {
use self::StatusCode::*;
matches!(self, Waiting | Queued | Started | InProgress | Summarized)
}
pub fn is_ready(self) -> bool {
self == StatusCode::Finished
}
pub fn is_err(self) -> bool {
self == StatusCode::Faulty || self == StatusCode::Unknown
}
}
impl<'de> Deserialize<'de> for StatusCode {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
match i64::deserialize(deserializer)? {
0 => Ok(StatusCode::Waiting),
1 => Ok(StatusCode::Queued),
2 => Ok(StatusCode::Started),
3 => Ok(StatusCode::InProgress),
4 => Ok(StatusCode::Summarized),
5 => Ok(StatusCode::Finished),
-1 => Ok(StatusCode::Faulty),
-2 => Ok(StatusCode::Unknown),
code => {
let unexpected = Unexpected::Signed(code);
let expected = "a number between -2 and 5";
Err(<D::Error as serde::de::Error>::invalid_value(
unexpected, &expected,
))
}
}
}
}
impl Serialize for StatusCode {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let code = match *self {
StatusCode::Waiting => 0,
StatusCode::Queued => 1,
StatusCode::Started => 2,
StatusCode::InProgress => 3,
StatusCode::Summarized => 4,
StatusCode::Finished => 5,
StatusCode::Faulty => -1,
StatusCode::Unknown => -2,
};
code.serialize(serializer)
}
}
pub trait Status {
fn code(&self) -> StatusCode;
fn message(&self) -> &str;
fn elapsed(&self) -> Option<u64>;
fn progress(&self) -> Option<f32>;
}
#[derive(Debug, Deserialize, Clone, Serialize)]
#[non_exhaustive]
pub struct GenericStatus {
pub code: StatusCode,
pub message: String,
pub elapsed: Option<u64>,
pub progress: Option<f32>,
}
impl Status for GenericStatus {
fn code(&self) -> StatusCode {
self.code
}
fn message(&self) -> &str {
&self.message
}
fn elapsed(&self) -> Option<u64> {
self.elapsed
}
fn progress(&self) -> Option<f32> {
self.progress
}
}