use std::time::Duration;
use std::time::{SystemTime, UNIX_EPOCH};
#[derive(PartialEq, Eq, Debug, Copy, Clone)]
pub enum TickUnit {
Nanos,
Micros,
Millis,
Secs,
}
impl TickUnit {
#[inline]
pub fn id(self) -> u8 {
match self {
TickUnit::Nanos => 9,
TickUnit::Micros => 6,
TickUnit::Millis => 3,
TickUnit::Secs => 0,
}
}
#[inline]
pub fn from_id(id: u8) -> TickUnit {
match id {
9 => TickUnit::Nanos,
6 => TickUnit::Micros,
3 => TickUnit::Millis,
0 => TickUnit::Secs,
_ => panic!("Unknown time unit id {}", id),
}
}
#[inline]
pub fn convert(self, duration: Duration) -> u64 {
match self {
TickUnit::Nanos => duration.as_nanos() as u64,
TickUnit::Micros => duration.as_micros() as u64,
TickUnit::Millis => duration.as_millis() as u64,
TickUnit::Secs => duration.as_secs(),
}
}
#[inline]
pub fn nix_time(self) -> u64 {
self.convert(SystemTime::now().duration_since(UNIX_EPOCH).unwrap())
}
}
#[cfg(test)]
mod tests {
use super::TickUnit::*;
use super::*;
use std::time::Duration;
#[test]
fn check_ids_symetry() {
assert_eq!(Nanos.id(), TickUnit::from_id(Nanos.id()).id());
assert_eq!(Micros.id(), TickUnit::from_id(Micros.id()).id());
assert_eq!(Millis.id(), TickUnit::from_id(Millis.id()).id());
assert_eq!(Secs.id(), TickUnit::from_id(Secs.id()).id());
}
#[test]
#[should_panic]
fn check_wrong_id() {
TickUnit::from_id(123);
}
#[test]
fn test_coversion() {
let duration = Duration::new(1, 500_000_000); assert_eq!(Nanos.convert(duration), 1_500_000_000);
assert_eq!(Micros.convert(duration), 1_500_000);
assert_eq!(Millis.convert(duration), 1_500);
assert_eq!(Secs.convert(duration), 1);
}
#[test]
fn check_ids() {
assert_eq!(Nanos.id(), 9);
assert_eq!(Micros.id(), 6);
assert_eq!(Millis.id(), 3);
assert_eq!(Secs.id(), 0);
}
#[test]
fn check_nix_time() {
let ticks = [Nanos, Micros, Millis];
let sleep_duration = std::time::Duration::from_millis(50);
for tick in &ticks {
let t1 = tick.nix_time();
std::thread::sleep(sleep_duration);
let t2 = tick.nix_time();
assert!(t1 < t2);
}
}
}