From 061eea0f03733b7b04d02d0b2379ab23c4c35050 Mon Sep 17 00:00:00 2001 From: holly sparkles Date: Sun, 14 Jan 2024 19:30:43 +0100 Subject: [PATCH] feat: add stopwatch functionality --- Cargo.lock | 7 +++++++ Cargo.toml | 8 ++++++++ src/lib.rs | 153 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 168 insertions(+) create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 src/lib.rs diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..3dab0cb --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "stopwatch" +version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..ebfd5b0 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "stopwatch" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..fd40ead --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,153 @@ +use std::fmt; +use std::time::{Duration, Instant}; + +/// Stopwatch is a simple utility for measuring elapsed time. +pub struct Stopwatch { + /// The time when the stopwatch was started. + start_time: Option, + /// The total elapsed time. + elapsed_time: Duration, +} + +impl Stopwatch { + /// Creates a new `Stopwatch` with initial values. + /// + /// # Examples + /// + /// ``` + /// use std::time::Duration; + /// use stopwatch::Stopwatch; + /// + /// let stopwatch = Stopwatch::new(); + /// + /// assert_eq!(stopwatch.elapsed(), Duration::from_secs(0)); + /// ``` + pub fn new() -> Stopwatch { + Stopwatch { + start_time: None, + elapsed_time: Duration::from_secs(0), + } + } + + /// Starts the stopwatch. If the stopwatch is already running, this has no effect. + /// + /// # Examples + /// + /// ``` + /// use stopwatch::Stopwatch; + /// + /// let mut stopwatch = Stopwatch::new(); + /// + /// stopwatch.start(); + /// + /// assert_eq!(stopwatch.is_running(), true); + /// ``` + pub fn start(&mut self) { + if self.start_time.is_none() { + self.start_time = Some(Instant::now()); + } + } + + /// Stops the stopwatch and adds the elapsed time since the start to the total elapsed time. + /// If the stopwatch is not running, this has no effect. + /// + /// # Examples + /// + /// ``` + /// use std::time::Duration; + /// use stopwatch::Stopwatch; + /// + /// let mut stopwatch = Stopwatch::new(); + /// + /// stopwatch.start(); + /// std::thread::sleep(std::time::Duration::from_secs(1)); + /// stopwatch.stop(); + /// + /// assert!(!stopwatch.is_running()) + /// ``` + pub fn stop(&mut self) { + if let Some(start_time) = self.start_time { + self.elapsed_time += Instant::now() - start_time; + self.start_time = None; + } + } + + /// Resets the stopwatch. If the stopwatch is currently running, stops it before resetting. + /// + /// # Examples + /// + /// ``` + /// use std::time::Duration; + /// use stopwatch::Stopwatch; + /// + /// let mut stopwatch = Stopwatch::new(); + /// + /// stopwatch.start(); + /// std::thread::sleep(std::time::Duration::from_secs(1)); + /// stopwatch.reset(); + /// + /// assert_eq!(stopwatch.elapsed(), Duration::from_secs(0)); + /// ``` + pub fn reset(&mut self) { + if self.is_running() { + self.stop(); + } + + self.start_time = None; + self.elapsed_time = Duration::from_secs(0); + } + + /// Gets the total elapsed time. If the stopwatch is running, adds the time since the start. + /// + /// # Examples + /// + /// ``` + /// use std::time::Duration; + /// use stopwatch::Stopwatch; + /// + /// let mut stopwatch = Stopwatch::new(); + /// + /// stopwatch.start(); + /// std::thread::sleep(Duration::from_secs(1)); + /// + /// assert_eq!(stopwatch.elapsed().as_secs(), 1); + /// ``` + pub fn elapsed(&self) -> Duration { + if let Some(start_time) = self.start_time { + if self.is_running() { + return Instant::now().duration_since(start_time); + } + } + + self.elapsed_time + } + + /// Checks if the stopwatch is currently running. + /// + /// # Examples + /// + /// ``` + /// use std::time::Duration; + /// use stopwatch::Stopwatch; + /// + /// let mut stopwatch = Stopwatch::new(); + /// assert!(!stopwatch.is_running()); + /// + /// stopwatch.start(); + /// assert!(stopwatch.is_running()); + /// + /// std::thread::sleep(Duration::from_secs(1)); + /// + /// stopwatch.stop(); + /// assert!(!stopwatch.is_running()); + /// ``` + pub fn is_running(&self) -> bool { + self.start_time.is_some() + } +} + +impl fmt::Display for Stopwatch { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{:.2?}", self.elapsed()) + } +} -- libgit2 1.7.2