1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
use std::time::{Duration, Instant, SystemTime};

/// A internal enum to manage stopwatch stopping
enum StopwatchState {
    Running,
    Paused,
}

/// The stopwatch uses the std::time Instant and Duration
pub struct Stopwatch {
    state: StopwatchState,
    duration: Duration,
    instant: Instant,
}

impl Stopwatch {
    pub fn new() -> Self {
        Self::default()
    }

    /// get the elapsed time since last restart
    pub fn elapsed(&self) -> Duration {
        match self.state {
            StopwatchState::Running => {
                self.duration + self.instant.elapsed()
            },
            StopwatchState::Paused => {
                self.duration
            },
        }

    }

    /// restart the stopwatch
    pub fn restart(&mut self) {
        self.duration = Duration::new(0, 0);
        self.instant = Instant::now();
        self.state = StopwatchState::Running;
    }

    /// pause the stopwatch
    pub fn pause(&mut self) {
        self.duration += self.instant.elapsed();
        self.state = StopwatchState::Paused;
    }

    /// unpause the stopwatch
    pub fn unpause(&mut self) {
        self.instant = Instant::now();
        self.state = StopwatchState::Running;
    }
}

impl Default for Stopwatch {
    fn default() -> Self {
        Self {
            state: StopwatchState::Running,
            duration: Duration::new(0, 0),
            instant: Instant::now(),
        }
    }
}

/// This stopwatch is the same as the normal stopwatch
/// but instead of using std::Instance, it uses std::SystemTime
/// See normal Stopwatch for documentation
pub struct SystemStopwatch {
    state: StopwatchState,
    duration: Duration,
    instant: SystemTime,
}

impl SystemStopwatch {
    pub fn new() -> Self {
        Self::default()
    }

    pub fn elapsed(&self) -> Duration {
        match self.state {
            StopwatchState::Running => {
                self.duration + self.instant.elapsed().unwrap()
            },
            StopwatchState::Paused => {
                self.duration
            },
        }

    }

    pub fn restart(&mut self) {
        self.duration = Duration::new(0, 0);
        self.instant = SystemTime::now();
        self.state = StopwatchState::Running;
    }

    pub fn pause(&mut self) {
        self.duration += self.instant.elapsed().unwrap();
        self.state = StopwatchState::Paused;
    }

    pub fn unpause(&mut self) {
        self.instant = SystemTime::now();
        self.state = StopwatchState::Running;
    }
}

impl Default for SystemStopwatch {
    fn default() -> Self {
        Self {
            state: StopwatchState::Running,
            duration: Duration::new(0, 0),
            instant: SystemTime::now(),
        }
    }
}