use serde::{self, Deserialize, Deserializer};
use serde::de::Unexpected;
use std::result;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum StatusCode {
Waiting,
Queued,
Started,
InProgress,
Summarized,
Finished,
Faulty,
Unknown,
}
impl StatusCode {
pub fn is_working(self) -> bool {
use self::StatusCode::*;
match self {
Waiting | Queued | Started | InProgress | Summarized => true,
_ => false,
}
}
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::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))
}
}
}
}
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)]
pub struct GenericStatus {
pub code: StatusCode,
pub message: String,
pub elapsed: Option<u64>,
pub progress: Option<f32>,
#[serde(default, skip_serializing)]
_hidden: (),
}
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
}
}