use std::fmt::{Display, Write};
use serde::{de::DeserializeOwned, Deserialize, Serialize};
#[non_exhaustive]
#[derive(Copy, Clone, Default, Debug, Serialize, Deserialize)]
pub enum StatusType {
#[default]
Uninitialized,
Initialized,
StepType,
Success,
Failed,
Custom,
}
impl Display for StatusType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
match self {
Self::Uninitialized => "Uninitialized",
Self::Initialized => "Initialized",
Self::StepType => "Step",
Self::Success => "Success",
Self::Failed => "Failed",
Self::Custom => "Message",
}
)
}
}
#[derive(Clone, Default, Debug, Serialize, Deserialize)]
pub struct StatusMessage {
pub status_type: StatusType,
pub text: String,
}
impl StatusMessage {
pub fn reset(&mut self) {
self.status_type = StatusType::Uninitialized;
self.text = "".to_string();
}
pub fn uninitialize(&mut self) {
self.reset()
}
pub fn initialize(&mut self) {
self.reset();
self.status_type = StatusType::Initialized;
}
pub fn set_initialized(mut self) -> Self {
self.initialize();
self
}
pub fn initialize_with_message(&mut self, message: &str) {
self.initialize();
self.text = message.to_string();
}
pub fn set_initialized_with_message(mut self, message: &str) -> Self {
self.initialize_with_message(message);
self
}
pub fn step(&mut self) {
self.reset();
self.status_type = StatusType::StepType;
}
pub fn set_step(mut self) -> Self {
self.step();
self
}
pub fn step_with_message(&mut self, message: &str) {
self.step();
self.text = message.to_string();
}
pub fn set_step_with_message(mut self, message: &str) -> Self {
self.step_with_message(message);
self
}
pub fn succeed(&mut self) {
self.reset();
self.status_type = StatusType::Success;
}
pub fn set_success(mut self) -> Self {
self.succeed();
self
}
pub fn succeed_with_message(&mut self, message: &str) {
self.succeed();
self.text = message.to_string();
}
pub fn set_success_with_message(mut self, message: &str) -> Self {
self.succeed_with_message(message);
self
}
pub fn fail(&mut self) {
self.reset();
self.status_type = StatusType::Failed;
}
pub fn set_failed(mut self) -> Self {
self.fail();
self
}
pub fn fail_with_message(&mut self, message: &str) {
self.fail();
self.text = message.to_string();
}
pub fn set_failed_with_message(mut self, message: &str) -> Self {
self.fail_with_message(message);
self
}
pub fn custom(&mut self, message: &str) {
self.reset();
self.status_type = StatusType::Custom;
self.text = message.to_string();
}
pub fn set_custom(mut self, message: &str) -> Self {
self.custom(message);
self
}
pub const fn success(&self) -> bool {
matches!(self.status_type, StatusType::Success)
}
}
impl Display for StatusMessage {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if self.text.is_empty() {
write!(f, "{}", self.status_type)
} else {
write!(f, "{}: {}", self.status_type, self.text)
}
}
}
pub trait Status: Clone + Default + Serialize + DeserializeOwned {
fn reset(&mut self);
fn success(&self) -> bool {
self.message().success()
}
fn message(&self) -> &StatusMessage;
fn set_message(&mut self) -> &mut StatusMessage;
}
pub trait ProgressStatus: Status {
fn write_progress(&self, out: &mut String) -> std::fmt::Result {
write!(out, "status={}", self.message())
}
}