use std::{fmt::Display, time::Duration}; use serde::{Deserialize, Serialize}; use crate::daemon::Timer; #[derive(Debug, Serialize, Deserialize, Clone)] pub struct Pomodoro { work: Duration, pause: Duration, long_pause: Duration, pauses_till_long: u64, pauses: u64, status: Status, pub timer: Timer, } impl Display for Pomodoro { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!( f, "Pomodoro ({}, {}, {}) currently {} with {} remaining.", humantime::format_duration(self.work), humantime::format_duration(self.pause), humantime::format_duration(self.long_pause), self.status, humantime::format_duration(self.timer.remaining()) ) } } #[derive(Debug, Serialize, Deserialize, Clone)] enum Status { Working, Pausing, LongPause, } impl Display for Status { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Status::Working => write!(f, "work"), Status::Pausing => write!(f, "pause"), Status::LongPause => write!(f, "long pause"), } } } impl Pomodoro { pub fn new( work: Duration, pause: Duration, long_pause: Duration, pauses_till_long: u64, ) -> Self { Pomodoro { work, pause, long_pause, pauses_till_long, pauses: 0, status: Status::Working, timer: Timer::new(Status::Working.to_string().into_boxed_str(), work), } } pub fn handle_expiration(&mut self, notify: bool) { self.timer.handle_expiration(notify); let duration = match self.status { Status::Working => { if self.pauses == self.pauses_till_long { self.long_pause } else { self.pause } } _ => self.work, }; self.status = match self.status { Status::Working => { if self.pauses == self.pauses_till_long { self.pauses = 0; Status::LongPause } else { self.pauses += 1; Status::Pausing } } _ => Status::Working, }; self.timer = Timer::new(self.status.to_string().into_boxed_str(), duration); } pub fn is_expired(&self) -> bool { self.timer.is_expired() } }