use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub(crate) enum SupportedPrecision {
Seconds, Milliseconds, Microseconds, Nanoseconds, Picoseconds, }
impl SupportedPrecision {
pub fn units(self) -> i32 {
match self {
SupportedPrecision::Seconds => 0,
SupportedPrecision::Milliseconds => 3,
SupportedPrecision::Microseconds => 6,
SupportedPrecision::Nanoseconds => 9,
SupportedPrecision::Picoseconds => 12,
}
}
pub fn from_units(units: i32) -> Option<Self> {
match units {
0 => Some(SupportedPrecision::Seconds),
3 => Some(SupportedPrecision::Milliseconds),
6 => Some(SupportedPrecision::Microseconds),
9 => Some(SupportedPrecision::Nanoseconds),
12 => Some(SupportedPrecision::Picoseconds),
_ => None,
}
}
pub fn subsecond_unit(self) -> Option<&'static str> {
match self {
SupportedPrecision::Seconds => None,
SupportedPrecision::Milliseconds => Some("ms"),
SupportedPrecision::Microseconds => Some("us"),
SupportedPrecision::Nanoseconds => Some("ns"),
SupportedPrecision::Picoseconds => Some("ps"),
}
}
pub fn from_subsecond_unit(unit: &str) -> Option<Self> {
match unit {
"ms" => Some(SupportedPrecision::Milliseconds),
"us" => Some(SupportedPrecision::Microseconds),
"ns" => Some(SupportedPrecision::Nanoseconds),
"ps" => Some(SupportedPrecision::Picoseconds),
_ => None,
}
}
}
impl fmt::Display for SupportedPrecision {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.units())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_units_roundtrip() {
for units in [0, 3, 6, 9, 12] {
let precision = SupportedPrecision::from_units(units).unwrap();
assert_eq!(precision.units(), units);
}
assert_eq!(SupportedPrecision::from_units(4), None);
assert_eq!(SupportedPrecision::from_units(13), None);
assert_eq!(SupportedPrecision::from_units(-1), None);
}
#[test]
fn test_subsecond_unit_roundtrip() {
for unit in ["ms", "us", "ns", "ps"] {
let precision = SupportedPrecision::from_subsecond_unit(unit).unwrap();
assert_eq!(precision.subsecond_unit(), Some(unit));
}
assert_eq!(SupportedPrecision::Seconds.subsecond_unit(), None);
assert_eq!(SupportedPrecision::from_subsecond_unit("s"), None);
}
}