timers/src/pomodoro.rs

99 lines
2.5 KiB
Rust

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 update(&mut self) {
if self.timer.is_expired() {
self.switch();
};
}
fn switch(&mut self) {
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);
}
}