index : stopwatch.git

ascending towards madness

author holly sparkles <sparkles@holly.sh> 2024-01-14 18:30:43.0 +00:00:00
committer holly sparkles <sparkles@holly.sh> 2024-01-14 18:30:43.0 +00:00:00
commit
061eea0f03733b7b04d02d0b2379ab23c4c35050 [patch]
tree
67dcb348f6b2ce852c8089c3ee18f7f2aa1c2561
parent
65a84cf9e7688712836b17bf768c131339a28951
download
061eea0f03733b7b04d02d0b2379ab23c4c35050.tar.gz

feat: add stopwatch functionality



Diff

 Cargo.lock |   7 +++-
 Cargo.toml |   8 +++-
 src/lib.rs | 153 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 168 insertions(+)

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<Instant>,
    /// 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())
    }
}