use std::fmt::{Debug, Display, Formatter};
use std::time::{SystemTime, UNIX_EPOCH};
use indexmap::IndexMap;
use log::warn;
use crate::client::command::Command;
#[derive(Clone, Debug, PartialEq)]
pub enum CommandState {
WAITING, RUNNING, COMPLETED, ABORTED,
}
impl Display for CommandState {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self)
}
}
#[derive(Clone, Debug)]
pub struct CommandDetails {
id: u128,
name: String,
properties: IndexMap<String, String>,
state: CommandState,
waiting_at: u128,
running_at: Option<u128>,
terminated_at: Option<u128>,
}
impl CommandDetails {
pub fn new(command: &Box<dyn Command>) -> Self {
let id = command.id();
let name = command.name();
let properties = command.properties();
let state = CommandState::WAITING;
let waiting_at = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis();
let running_at = None;
let terminated_at = None;
Self { id, name, properties, state, waiting_at, running_at, terminated_at }
}
pub fn set_state(&mut self, state: CommandState) {
self.state = state;
match self.state {
CommandState::RUNNING =>
self.running_at = Some(SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis()),
CommandState::COMPLETED | CommandState::ABORTED =>
self.terminated_at = Some(SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis()),
_ => warn!("can only change command state to running, completed or aborted"),
}
}
pub fn id(&self) -> u128 {
self.id
}
pub fn name(&self) -> &String {
&self.name
}
pub fn properties(&self) -> &IndexMap<String, String> {
&self.properties
}
pub fn state(&self) -> &CommandState {
&self.state
}
pub fn waiting_at(&self) -> u128 {
self.waiting_at
}
pub fn running_at(&self) -> Option<u128> {
self.running_at
}
pub fn terminated_at(&self) -> Option<u128> {
self.terminated_at
}
}
impl Display for CommandDetails {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let mut properties = String::new();
self.properties.iter().for_each(|(k, v)| properties += &format!("{}: {},", k, v).as_str());
let running_at = match self.running_at {
Some(i) => format!("{}", i),
None => "".to_string(),
};
let terminated_at = match self.terminated_at {
Some(i) => format!("{}", i),
None => "".to_string(),
};
write!(f,
"id: [{}], name: [{}], properties: [{}], state: [{}], waiting_at: [{}], running_at: [{}], terminated_at: [{}]",
self.id, self.name, properties, self.state, self.waiting_at, running_at, terminated_at
)
}
}