clock_timer/
lib.rs

1pub mod timer {
2    use std::{io::Write, thread, time::Duration};
3
4    #[derive(Clone, Copy, Debug)]
5    pub struct TimerStruct {
6        pub duration: u32,
7        pub hours: u32,
8        pub minutes: u32,
9        pub seconds: u32,
10    }
11
12    impl TimerStruct {
13        pub fn new(hours: u32, minutes: u32, seconds: u32) -> Result<TimerStruct, &'static str> {
14            let duration = (hours * 3600) + (minutes * 60) + seconds;
15            if duration == 0 {
16                return Err("Duration need to be 1 or more seconds.");
17            }
18
19            Ok(TimerStruct {
20                duration,
21                hours,
22                minutes,
23                seconds,
24            })
25        }
26
27        pub fn start_timer<W: Write>(&self, writer: &mut W) {
28            let mut current_duration = self.duration;
29            let one_second = Duration::from_secs(1);
30
31            loop {
32                // Calculate display components from the current total duration
33                let display_hours = current_duration / 3600;
34                let remaining_seconds_after_hours = current_duration % 3600;
35                let display_minutes = remaining_seconds_after_hours / 60;
36                let display_seconds = remaining_seconds_after_hours % 60;
37
38                let time_display_string =
39                    format!("{}:{}:{}", display_hours, display_minutes, display_seconds);
40
41                if current_duration == 0 {
42                    // If duration is 0, this is the final display. Print with a newline and break.
43                    writeln!(writer, "{}", time_display_string).unwrap();
44                    break;
45                } else {
46                    // For all other durations, print with a carriage return to overwrite the line.
47                    write!(writer, "{}\r", time_display_string).unwrap();
48                    writer.flush().unwrap(); // Ensure the output is flushed immediately
49                }
50
51                thread::sleep(one_second);
52                current_duration -= 1;
53            }
54        }
55    }
56}
57
58pub use timer::TimerStruct;