fine_grained/
stopwatch.rs1use std::fmt;
10
11use time;
12
13#[derive(Clone, Debug, Default)]
15pub struct Stopwatch {
16 laps: Vec<u64>,
18
19 start_time: Option<u64>,
21
22 total_time: u64
24}
25
26impl Stopwatch {
27 pub fn new() -> Stopwatch {
29 Stopwatch { laps: vec![], start_time: None, total_time: 0 }
30 }
31
32 pub fn start_new() -> Stopwatch {
34 let mut stopwatch = Stopwatch::new();
35 stopwatch.start();
36 stopwatch
37 }
38
39 pub fn start(&mut self) {
41 self.start_time = Some(time::precise_time_ns());
42 }
43
44 pub fn lap(&mut self) -> u64 {
48 let current_time: u64 = time::precise_time_ns();
50 let lap: u64 = match self.start_time {
51 Some(t) => current_time - t,
52 None => return 0
53 };
54
55 self.total_time += lap;
58 self.laps.push(lap);
59 self.start_time = Some(current_time);
60
61 lap
62 }
63
64 pub fn stop(&mut self) {
68 self.start_time = None;
69 }
70
71 pub fn reset(&mut self) {
73 self.laps = vec![];
74 self.start_time = None;
75 self.total_time = 0;
76 }
77
78 pub fn restart(&mut self) {
80 self.reset();
81 self.start();
82 }
83
84 pub fn total_time(&self) -> u64 {
89 match self.start_time {
90 Some(current_lap_start_time) => {
91 let current_time: u64 = time::precise_time_ns();
94 let lap: u64 = current_time - current_lap_start_time;
95 self.total_time + lap
96 },
97 None => self.total_time
98 }
99 }
100
101 pub fn laps(&self) -> &Vec<u64> {
103 &self.laps
104 }
105
106 pub fn number_of_laps(&self) -> usize {
108 self.laps.len()
109 }
110
111 pub fn is_running(&self) -> bool {
113 self.start_time.is_some()
114 }
115}
116
117impl fmt::Display for Stopwatch {
118 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
120 write!(formatter, "{total_time}ns", total_time = self.total_time())
121 }
122}
123
124#[cfg(test)]
125mod tests {
126 #![allow(unused_results)]
127
128 use super::Stopwatch;
129
130 #[test]
131 fn new() {
132 let stopwatch = Stopwatch::new();
133 assert_eq!(stopwatch.laps, vec![]);
134 assert_eq!(stopwatch.start_time, None);
135 assert_eq!(stopwatch.total_time, 0);
136 }
137
138 #[test]
139 fn start_new() {
140 let stopwatch = Stopwatch::start_new();
141 assert_eq!(stopwatch.laps, vec![]);
142 assert!(stopwatch.start_time.is_some());
143 assert_eq!(stopwatch.total_time, 0);
144 }
145
146 #[test]
147 fn start() {
148 let mut stopwatch = Stopwatch::new();
149 stopwatch.start();
150 assert!(stopwatch.start_time.is_some());
151 }
152
153 #[test]
154 fn lap() {
155 let mut stopwatch = Stopwatch::new();
156 let lap_0: u64 = stopwatch.lap();
157 assert_eq!(lap_0, 0);
158 assert_eq!(stopwatch.laps.len(), 0);
159 assert_eq!(stopwatch.total_time, lap_0);
160
161 stopwatch.start();
162 let lap_1: u64 = stopwatch.lap();
163 assert!(lap_1 > 0);
164 assert_eq!(stopwatch.laps.len(), 1);
165 assert_eq!(stopwatch.laps[0], lap_1);
166 assert_eq!(stopwatch.total_time, lap_1);
167
168 let lap_2: u64 = stopwatch.lap();
169 assert!(lap_2 > 0);
170 assert_eq!(stopwatch.laps.len(), 2);
171 assert_eq!(stopwatch.laps[0], lap_1);
172 assert_eq!(stopwatch.laps[1], lap_2);
173 assert_eq!(stopwatch.total_time, lap_1 + lap_2);
174 }
175
176 #[test]
177 fn stop() {
178 let mut stopwatch = Stopwatch::start_new();
179 let lap: u64 = stopwatch.lap();
180 stopwatch.stop();
181 assert!(stopwatch.start_time.is_none());
182 assert_eq!(stopwatch.laps.len(), 1);
183 assert_eq!(stopwatch.total_time, lap);
184 }
185
186 #[test]
187 fn reset() {
188 let mut stopwatch = Stopwatch::start_new();
189 stopwatch.lap();
190 stopwatch.reset();
191 assert_eq!(stopwatch.laps, vec![]);
192 assert_eq!(stopwatch.start_time, None);
193 assert_eq!(stopwatch.total_time, 0);
194 }
195
196 #[test]
197 fn restart() {
198 let mut stopwatch = Stopwatch::start_new();
199 stopwatch.lap();
200 stopwatch.restart();
201 assert_eq!(stopwatch.laps, vec![]);
202 assert!(stopwatch.start_time.is_some());
203 assert_eq!(stopwatch.total_time, 0);
204 }
205
206 #[test]
207 fn total_time() {
208 let mut stopwatch = Stopwatch::start_new();
209 let start_time: u64 = stopwatch.start_time.unwrap();
210 let mut total_time: u64 = stopwatch.total_time();
211 assert!(total_time > 0);
212 assert_eq!(stopwatch.total_time, 0);
213 assert_eq!(stopwatch.laps, vec![]);
214 assert_eq!(stopwatch.start_time.unwrap(), start_time);
215
216 stopwatch.lap();
217 stopwatch.stop();
218 total_time = stopwatch.total_time();
219 assert_eq!(total_time, stopwatch.total_time);
220 }
221
222 #[test]
223 fn laps() {
224 let mut stopwatch = Stopwatch::start_new();
225 stopwatch.lap();
226 stopwatch.lap();
227 stopwatch.lap();
228
229 assert_eq!(stopwatch.laps(), &stopwatch.laps);
230 }
231
232 #[test]
233 fn number_of_laps() {
234 let mut stopwatch = Stopwatch::start_new();
235 stopwatch.lap();
236 stopwatch.lap();
237 stopwatch.lap();
238
239 assert_eq!(stopwatch.number_of_laps(), 3);
240 }
241
242 #[test]
243 fn is_running() {
244 let mut stopwatch = Stopwatch::new();
245 assert!(!stopwatch.is_running());
246
247 stopwatch.start();
248 assert!(stopwatch.is_running());
249 }
250
251 #[test]
252 fn fmt_display() {
253 let mut stopwatch = Stopwatch::new();
254 stopwatch.total_time = 42;
255 assert_eq!(format!("{stopwatch}", stopwatch = stopwatch), "42ns");
256 }
257}