use std::{
collections::HashMap,
time::{Duration, SystemTime},
};
pub struct Timer {
timers: HashMap<String, (SystemTime, SystemTime, bool)>,
}
impl Timer {
pub fn new() -> Timer {
Timer {
timers: HashMap::new(),
}
}
pub fn start(&mut self, msg: &str) {
self.timers.insert(
msg.to_string(),
(SystemTime::now(), SystemTime::now(), false),
);
}
pub fn get(&self, msg: &str) -> Option<Duration> {
self.timers.get(msg).map(|time| {
time.0
.elapsed()
.unwrap_or_else(|_| Duration::from_micros(0))
})
}
pub fn stop(&mut self, msg: &str) -> Option<Duration> {
self.timers.remove(msg).map(|time| {
time.0
.elapsed()
.unwrap_or_else(|_| Duration::from_micros(0))
})
}
pub fn reset(&mut self, msg: &str) -> Option<Duration> {
self.timers
.insert(
msg.to_string(),
(SystemTime::now(), SystemTime::now(), false),
)
.map(|time| {
time.0
.elapsed()
.unwrap_or_else(|_| Duration::from_micros(0))
})
}
pub fn pause(&mut self, msg: &str) -> Option<Duration> {
if self.timers.contains_key(msg) {
let timer = self.timers.entry(msg.to_string()).or_insert((
SystemTime::now(),
SystemTime::now(),
false,
));
if timer.2 {
return None;
}
timer.1 = SystemTime::now();
timer.2 = true;
Some(
timer
.0
.elapsed()
.unwrap_or_else(|_| Duration::from_micros(0)),
)
} else {
None
}
}
pub fn resume(&mut self, msg: &str) -> Option<Duration> {
if self.timers.contains_key(msg) {
let timer = self.timers.entry(msg.to_string()).or_insert((
SystemTime::now(),
SystemTime::now(),
false,
));
if timer.2 {
timer.2 = false;
timer.0 = timer
.0
.checked_add(
timer
.1
.elapsed()
.unwrap_or_else(|_| Duration::from_micros(0)),
)
.unwrap_or_else(SystemTime::now);
}
Some(
timer
.0
.elapsed()
.unwrap_or_else(|_| Duration::from_micros(0)),
)
} else {
None
}
}
}
impl Default for Timer {
fn default() -> Self {
Timer::new()
}
}