use std::time::{Duration, Instant};
pub struct Timer {
start: Instant,
target: Option<Duration>,
stopped: Option<Duration>,
}
impl Timer {
pub fn new() -> Self {
Timer {
start: Instant::now(),
target: None,
stopped: None,
}
}
pub fn with_target(duration: Duration) -> Self {
Timer {
start: Instant::now(),
target: Some(duration),
stopped: None,
}
}
pub fn set_target(&mut self, target: Option<Duration>) {
self.target = target
}
pub fn target(&self) -> Option<Duration> {
self.target
}
pub fn duration(&self) -> Duration {
match self.stopped {
None => Instant::now().saturating_duration_since(self.start),
Some(duration) => duration,
}
}
pub fn stop(&mut self) -> Duration {
self.stopped = Some(Instant::now().saturating_duration_since(self.start));
self.stopped.unwrap()
}
pub fn reset(&mut self) {
self.start = Instant::now();
self.stopped = None
}
pub fn running(&self) -> bool {
self.stopped.is_none()
}
pub fn stopped(&self) -> bool {
self.stopped.is_some()
}
pub fn signaled(&self) -> bool {
match self.target {
Some(target) => self.duration() >= target,
None => false,
}
}
pub fn remaining(&self) -> Option<Duration> {
if self.stopped.is_some() {
return None;
}
match self.target {
Some(target) => {
target.checked_sub(Instant::now().saturating_duration_since(self.start))
}
None => None,
}
}
pub fn remaining_ms(&self) -> Option<usize> {
self.remaining().map(|d| d.as_millis() as usize)
}
pub fn remaining_us(&self) -> Option<usize> {
self.remaining().map(|d| d.as_micros() as usize)
}
pub fn remaining_f32(&self) -> Option<f32> {
self.remaining().map(|d| d.as_secs_f32())
}
}