use super::format_nanoseconds;
use std::fmt;
use std::time::Instant;
#[derive(Clone, Copy, Debug)]
pub struct Stopwatch {
initial_time: Instant,
final_time: Instant,
}
impl Stopwatch {
pub fn new() -> Self {
let now = Instant::now();
Stopwatch {
initial_time: now,
final_time: now,
}
}
pub fn stop(&mut self) -> u128 {
self.final_time = Instant::now();
self.final_time.duration_since(self.initial_time).as_nanos()
}
pub fn reset(&mut self) {
let now = Instant::now();
self.initial_time = now;
self.final_time = now;
}
pub fn stop_and_reset(&mut self) -> u128 {
self.final_time = Instant::now();
let elapsed = self.final_time.duration_since(self.initial_time).as_nanos();
let now = Instant::now();
self.initial_time = now;
self.final_time = now;
elapsed
}
}
impl fmt::Display for Stopwatch {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let delta = self.final_time.duration_since(self.initial_time);
write!(f, "{}", format_nanoseconds(delta.as_nanos())).unwrap();
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::Stopwatch;
use std::thread::sleep;
use std::time::Duration;
#[test]
fn clone_copy_and_debug_work() {
let sw = Stopwatch::new();
let copy = sw;
let clone = sw.clone();
assert_eq!(copy.initial_time, sw.initial_time);
assert_eq!(clone.initial_time, sw.initial_time);
assert!(format!("{:?}", sw).len() > 0);
}
#[test]
fn new_and_display_work() {
let sw1 = Stopwatch::new();
assert_eq!(format!("{}", sw1), "0ns");
}
#[test]
fn stop_works() {
let mut sw = Stopwatch::new();
sleep(Duration::new(0, 1_000));
let elapsed = sw.stop();
assert!(elapsed > 0);
}
#[test]
fn reset_works() {
let mut sw = Stopwatch::new();
sleep(Duration::new(0, 1_000));
let mut elapsed = sw.stop();
assert!(elapsed > 0);
sw.reset();
let delta = sw.final_time.duration_since(sw.initial_time);
assert_eq!(delta.as_nanos(), 0);
sleep(Duration::new(0, 1_000));
elapsed = sw.stop();
assert!(elapsed > 0);
}
#[test]
fn stop_and_reset_works() {
let mut sw = Stopwatch::new();
sleep(Duration::new(0, 1_000));
let elapsed = sw.stop_and_reset();
assert!(elapsed > 0);
let delta = sw.final_time.duration_since(sw.initial_time);
assert_eq!(delta.as_nanos(), 0);
}
}