From 71eb940afc4d867493cb95655c6f718a19f50de8 Mon Sep 17 00:00:00 2001 From: Stevan Freeborn Date: Tue, 28 Jul 2026 15:17:58 -0500 Subject: [PATCH] refactor: store config on termato state --- src/app.rs | 88 +++++++++++++++++++++++------------------------------ src/main.rs | 4 +-- 2 files changed, 39 insertions(+), 53 deletions(-) diff --git a/src/app.rs b/src/app.rs index 81226c9..23d50a7 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,3 +1,4 @@ +use crate::args::CliConfig; use crate::constants::SECONDS_PER_MIN; use crate::msg::Message; use crate::notification::send_desktop_notification; @@ -10,30 +11,25 @@ pub enum TimerMode { } pub struct Termato { - pub work_mins: u32, - pub break_mins: u32, + pub config: CliConfig, pub mode: TimerMode, pub is_running: bool, pub duration_in_secs: u32, pub time_remaining_in_sec: u32, pub show_help: bool, - pub enable_notifications: bool, - pub enable_sound: bool, should_quit: bool, } impl Termato { - pub fn new(work_mins: u32, break_mins: u32) -> Self { + pub fn new(config: CliConfig) -> Self { + let duration_in_secs = config.work_mins * SECONDS_PER_MIN; Termato { - work_mins, - break_mins, + config, mode: TimerMode::Work, is_running: false, - duration_in_secs: work_mins * SECONDS_PER_MIN, - time_remaining_in_sec: work_mins * SECONDS_PER_MIN, + duration_in_secs, + time_remaining_in_sec: duration_in_secs, show_help: false, - enable_notifications: false, - enable_sound: false, should_quit: false, } } @@ -42,16 +38,6 @@ impl Termato { self.should_quit } - pub fn with_notifications(mut self, enable: bool) -> Self { - self.enable_notifications = enable; - self - } - - pub fn with_sound(mut self, enable: bool) -> Self { - self.enable_sound = enable; - self - } - pub fn update(&mut self, msg: Message) { match msg { Message::Tick => self.tick(), @@ -73,8 +59,8 @@ impl Termato { TimerMode::Break => TimerMode::Work, }; self.duration_in_secs = match self.mode { - TimerMode::Work => self.work_mins * SECONDS_PER_MIN, - TimerMode::Break => self.break_mins * SECONDS_PER_MIN, + TimerMode::Work => self.config.work_mins * SECONDS_PER_MIN, + TimerMode::Break => self.config.break_mins * SECONDS_PER_MIN, }; self.time_remaining_in_sec = self.duration_in_secs; } @@ -84,14 +70,14 @@ impl Termato { self.time_remaining_in_sec -= 1; if self.time_remaining_in_sec == 0 { - if self.enable_notifications { + if self.config.enable_notifications { match self.mode { TimerMode::Work => send_desktop_notification("Work Done", "Time to take a break."), TimerMode::Break => send_desktop_notification("Break Over", "Time to focus."), } } - if self.enable_sound { + if self.config.enable_sound { play_notification_sound(); } @@ -103,7 +89,7 @@ impl Termato { pub fn reset(&mut self) { self.is_running = false; self.mode = TimerMode::Work; - self.duration_in_secs = self.work_mins * SECONDS_PER_MIN; + self.duration_in_secs = self.config.work_mins * SECONDS_PER_MIN; self.time_remaining_in_sec = self.duration_in_secs; } @@ -116,24 +102,35 @@ impl Termato { mod tests { use super::*; + fn get_test_config(work_mins: u32, break_mins: u32) -> CliConfig { + CliConfig { + work_mins, + break_mins, + enable_notifications: false, + enable_sound: false, + enable_visualizer: false, + } + } + #[test] fn termato_new_when_called_it_should_return_expected_starting_state() { - let result = Termato::new(25, 5); + let result = Termato::new(get_test_config(25, 5)); - assert_eq!(result.work_mins, 25); - assert_eq!(result.break_mins, 5); + assert_eq!(result.config.work_mins, 25); + assert_eq!(result.config.break_mins, 5); assert_eq!(result.mode, TimerMode::Work); assert!(!result.is_running); assert_eq!(result.duration_in_secs, 1500); assert_eq!(result.time_remaining_in_sec, 1500); assert!(!result.show_help); - assert!(!result.enable_notifications); + assert!(!result.config.enable_notifications); + assert!(!result.config.enable_sound); assert!(!result.should_quit); } #[test] fn termato_update_when_called_with_messages_it_should_update_state() { - let mut termato = Termato::new(25, 5); + let mut termato = Termato::new(get_test_config(25, 5)); termato.update(Message::ToggleRunning); assert!(termato.is_running); @@ -154,7 +151,7 @@ mod tests { #[test] fn termato_tick_when_called_and_not_running_it_should_do_nothing() { - let mut termato = Termato::new(1, 1); + let mut termato = Termato::new(get_test_config(1, 1)); termato.update(Message::Tick); @@ -163,7 +160,7 @@ mod tests { #[test] fn termato_tick_when_called_and_no_time_remaining_it_should_do_nothing() { - let mut termato = Termato::new(1, 1); + let mut termato = Termato::new(get_test_config(1, 1)); termato.is_running = true; termato.time_remaining_in_sec = 0; @@ -174,7 +171,7 @@ mod tests { #[test] fn termato_tick_when_running_and_time_reamining_it_should_reduce_remaining_by_one() { - let mut termato = Termato::new(1, 1); + let mut termato = Termato::new(get_test_config(1, 1)); termato.is_running = true; termato.update(Message::Tick); @@ -184,7 +181,7 @@ mod tests { #[test] fn termato_tick_when_running_on_work_and_time_remaining_reaches_zero_it_should_toggle_to_break() { - let mut termato = Termato::new(1, 2); + let mut termato = Termato::new(get_test_config(1, 2)); termato.is_running = true; termato.time_remaining_in_sec = 1; @@ -197,7 +194,7 @@ mod tests { #[test] fn termato_tick_when_running_on_break_and_time_remaining_reaches_zero_it_should_toggle_to_work() { - let mut termato = Termato::new(2, 1); + let mut termato = Termato::new(get_test_config(2, 1)); termato.mode = TimerMode::Break; termato.is_running = true; termato.time_remaining_in_sec = 1; @@ -211,7 +208,7 @@ mod tests { #[test] fn termato_toggle_mode_when_called_it_should_toggle_the_mode() { - let mut termato = Termato::new(2, 1); + let mut termato = Termato::new(get_test_config(2, 1)); termato.toggle_mode(); assert_eq!(termato.mode, TimerMode::Break); @@ -226,7 +223,7 @@ mod tests { #[test] fn termato_toggle_running_when_called_and_already_running_it_should_pause() { - let mut termato = Termato::new(1, 1); + let mut termato = Termato::new(get_test_config(1, 1)); termato.is_running = true; termato.toggle_running(); @@ -236,7 +233,7 @@ mod tests { #[test] fn termato_toggle_running_when_called_and_already_paused_it_should_run() { - let mut termato = Termato::new(1, 1); + let mut termato = Termato::new(get_test_config(1, 1)); termato.toggle_running(); @@ -245,7 +242,7 @@ mod tests { #[test] fn termato_rest_when_called_it_should_reset_the_apps_state() { - let mut termato = Termato::new(1, 1); + let mut termato = Termato::new(get_test_config(1, 1)); termato.is_running = true; termato.mode = TimerMode::Break; termato.duration_in_secs = 1; @@ -261,7 +258,7 @@ mod tests { #[test] fn termato_toggle_help_when_called_it_should_toggle_help() { - let mut termato = Termato::new(1, 1); + let mut termato = Termato::new(get_test_config(1, 1)); termato.toggle_help(); @@ -271,13 +268,4 @@ mod tests { assert!(!termato.show_help); } - - #[test] - fn termato_notifications_when_called_it_should_verify_opt_in_behavior() { - let result = Termato::new(25, 5); - assert!(!result.enable_notifications); - - let result = result.with_notifications(true); - assert!(result.enable_notifications); - } } diff --git a/src/main.rs b/src/main.rs index abd921e..b069327 100644 --- a/src/main.rs +++ b/src/main.rs @@ -61,9 +61,7 @@ fn main() -> Result<(), io::Error> { None }; - let mut termato = Termato::new(config.work_mins, config.break_mins) - .with_notifications(config.enable_notifications) - .with_sound(config.enable_sound); + let mut termato = Termato::new(config); let (tx, rx) = mpsc::channel();