use std::time::{Duration, Instant};
#[derive(Debug)]
pub struct Stopwatch {
state: State,
}
#[derive(Debug)]
enum State {
Stopped,
Running { start_time: Instant, accumulated: Duration },
Paused { accumulated: Duration },
}
impl Default for Stopwatch {
fn default() -> Self {
Self::new()
}
}
impl Stopwatch {
pub fn new() -> Self {
Self { state: State::Stopped }
}
pub fn start(&mut self) {
match self.state {
State::Stopped => {
self.state = State::Running { start_time: Instant::now(), accumulated: Duration::new(0, 0) };
}
State::Paused { accumulated } => {
self.state = State::Running { start_time: Instant::now(), accumulated };
}
State::Running { .. } => {}
}
}
pub fn pause(&mut self) {
if let State::Running { start_time, accumulated } = self.state {
let elapsed = start_time.elapsed();
self.state = State::Paused { accumulated: accumulated + elapsed };
}
}
pub fn reset(&mut self) {
self.state = State::Stopped;
}
pub fn elapsed(&self) -> Duration {
match self.state {
State::Stopped => Duration::new(0, 0),
State::Paused { accumulated } => accumulated,
State::Running { start_time, accumulated } => accumulated + start_time.elapsed(),
}
}
pub fn is_paused(&self) -> bool {
matches!(self.state, State::Paused { .. })
}
pub fn is_stopped(&self) -> bool {
matches!(self.state, State::Stopped)
}
}