use std::time::{Duration, SystemTime, SystemTimeError};
pub struct Timer {
name: String,
start: SystemTime,
time_taken: Option<Duration>,
}
impl Timer {
pub fn new<S: AsRef<str>>(name: S) -> Self {
Self {
name: name.as_ref().to_owned(),
start: SystemTime::now(),
time_taken: None,
}
}
pub fn elapsed_millis(&mut self) -> Result<u128, SystemTimeError> {
self.elapsed().map(|d| d.as_millis())
}
pub fn elapsed(&mut self) -> Result<Duration, SystemTimeError> {
if let Some(d) = self.time_taken {
Ok(d)
} else {
let d = self.start.elapsed()?;
self.time_taken = Some(d);
Ok(d)
}
}
pub fn elapsed_no_cache(&self) -> Result<Duration, SystemTimeError> {
self.start.elapsed()
}
pub fn name(&self) -> &str {
&self.name
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn elapsed_millis() {
let mut timer = Timer::new("fake network request");
std::thread::sleep(Duration::from_secs_f64(0.025));
let elapsed = timer.elapsed_millis().expect("time went backwards!");
assert!(elapsed >= 25);
println!("`{}` took {elapsed} milliseconds", timer.name());
}
}