use serde::{Deserialize, Serialize};
use std::str::FromStr;
#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Default, Hash, PartialOrd)]
#[serde(rename_all = "snake_case")]
pub enum TimeUnit {
Hours,
#[default]
Minutes,
Seconds,
Milliseconds,
}
impl TimeUnit {
pub fn to_uom(&self, value: f64) -> uom::si::f64::Time {
match self {
TimeUnit::Hours => uom::si::f64::Time::new::<uom::si::time::hour>(value),
TimeUnit::Minutes => uom::si::f64::Time::new::<uom::si::time::minute>(value),
TimeUnit::Seconds => uom::si::f64::Time::new::<uom::si::time::second>(value),
TimeUnit::Milliseconds => uom::si::f64::Time::new::<uom::si::time::millisecond>(value),
}
}
pub fn from_uom(&self, value: uom::si::f64::Time) -> f64 {
match self {
TimeUnit::Hours => value.get::<uom::si::time::hour>(),
TimeUnit::Minutes => value.get::<uom::si::time::minute>(),
TimeUnit::Seconds => value.get::<uom::si::time::second>(),
TimeUnit::Milliseconds => value.get::<uom::si::time::millisecond>(),
}
}
}
impl std::fmt::Display for TimeUnit {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let s = serde_json::to_string(self)
.map_err(|_| std::fmt::Error)?
.replace('\"', "");
write!(f, "{s}")
}
}
impl FromStr for TimeUnit {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"hour" | "hours" | "hr" | "hrs" | "h" => Ok(TimeUnit::Hours),
"minute" | "minutes" | "min" | "mins" | "m" => Ok(TimeUnit::Minutes),
"second" | "seconds" | "sec" | "secs" | "s" => Ok(TimeUnit::Seconds),
"millisecond" | "milliseconds" | "ms" => Ok(TimeUnit::Milliseconds),
_ => Err(format!("unknown time unit '{s}'")),
}
}
}
impl TryFrom<String> for TimeUnit {
type Error = String;
fn try_from(value: String) -> Result<Self, Self::Error> {
Self::from_str(&value)
}
}