1use crate::numbers;
2use std::time::Instant;
3use cursive::{
4 View,
5 Printer,
6};
7
8pub struct Timer {
9 timer: Instant,
10 is_paused: bool,
11 pause_start: Instant,
12}
13
14impl Default for Timer {
15 fn default() -> Self {
16 Self::new()
17 }
18}
19
20impl Timer {
21 pub fn new() -> Self {
22 let now = Instant::now();
23 Self {
24 timer: now,
25 is_paused: false,
26 pause_start: now,
27 }
28 }
29
30 pub fn renew(&mut self) {
31 let now = Instant::now();
32 self.timer = now;
33 self.pause_start = now;
34 self.is_paused = false;
35 }
36
37 pub fn toggle_pause(&mut self) {
38 if self.is_paused {
39 self.timer += Instant::now() - self.pause_start;
40 } else {
41 self.pause_start = Instant::now();
42 }
43 self.is_paused = !self.is_paused;
44 }
45
46 pub fn reset(&mut self) {
47 let now = Instant::now();
48 self.timer = now;
49 self.pause_start = now;
50 }
51
52 pub fn time2str(&self) -> String {
53 let (mins, secs, mills) = self.elapsed();
54 let mins = numbers::padding(mins as usize, 2);
55 let secs = numbers::padding(secs as usize, 2);
56 let mills = numbers::padding(mills as usize, 3);
57 format!("Time {}:{}:{}", mins, secs, mills)
58 }
59
60 fn elapsed(&self) -> (u128, u128, u128) {
61 let mills = if self.is_paused {
62 (self.pause_start - self.timer).as_millis()
63 } else { self.timer.elapsed().as_millis() };
64 let mins = mills / 60000;
65 let secs = (mills % 60000) / 1000;
66 let mills = mills % 1000;
67 (mins, secs, mills)
68 }
69}
70
71impl View for Timer {
72 fn draw(&self, printer: &Printer) {
73 printer.print((0, 0), &self.time2str());
74 }
75
76 fn required_size(&mut self, _: cursive::Vec2) -> cursive::Vec2 {
77 let line = self.time2str();
78 cursive::Vec2::new(line.len() + 3, 1)
79 }
80}