diff options
author | Silas Bartha <[email protected]> | 2023-11-10 22:56:28 -0500 |
---|---|---|
committer | Silas Bartha <[email protected]> | 2023-11-10 22:56:28 -0500 |
commit | 5072b84d03df22efd375e4a8cfbf9740e62854fd (patch) | |
tree | a5d7e1f3d03a65cdac2b50b8f04cb6b56eb7d068 /src/main.rs |
basic daemon setup
Diffstat (limited to 'src/main.rs')
-rw-r--r-- | src/main.rs | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..6be031c --- /dev/null +++ b/src/main.rs @@ -0,0 +1,128 @@ +use std::{ + sync::{Arc, Mutex}, + time::{Duration, Instant}, +}; + +use zbus::{dbus_interface, ConnectionBuilder, Result}; + +use notify_rust::Notification; + +const WORK_DURATION_SECS: f32 = 15.0 * 60.0; +const SHORT_BREAK_DURATION_SECS: f32 = 5.0 * 60.0; +const LONG_BREAK_DURATION_SECS: f32 = 15.0 * 60.0; +const NUM_ITERATIONS: u8 = 4; + +struct Pomd { + remaining: Duration, + iteration: u8, + running: bool, + on_break: bool, + last_instant: Instant, +} + +#[derive(Default)] +struct PomdInterface { + data: Arc<Mutex<Pomd>>, +} + +#[dbus_interface(name = "dev.exvacuum.pomd")] +impl PomdInterface { + async fn get_remaining(&self) -> Duration { + self.data.lock().unwrap().remaining + } + + async fn get_iteration(&self) -> u8 { + self.data.lock().unwrap().iteration + } + + async fn is_running(&self) -> bool { + self.data.lock().unwrap().running + } + + async fn is_on_break(&self) -> bool { + self.data.lock().unwrap().on_break + } + + async fn start(&self) { + self.data.lock().unwrap().running = true; + } + + async fn pause(&self) { + self.data.lock().unwrap().running = false; + } + + async fn stop(&self) { + *self.data.lock().unwrap() = Pomd::default(); + } + + async fn skip(&self) { + self.data.lock().unwrap().running = false; + self.data.lock().unwrap().setup_next_iteration(); + } +} + +impl Default for Pomd { + fn default() -> Self { + Self { + remaining: Duration::from_secs_f32(WORK_DURATION_SECS), + iteration: 0, + running: false, + on_break: false, + last_instant: Instant::now(), + } + } +} + +impl Pomd { + fn update(&mut self) { + let elapsed = self.last_instant.elapsed(); + self.last_instant = Instant::now(); + if self.running { + if self.remaining > elapsed { + self.remaining -= elapsed; + } else { + self.running = false; + self.notify(); + self.setup_next_iteration(); + } + } + } + + fn setup_next_iteration(&mut self) { + self.on_break ^= true; + self.remaining = if self.on_break { + if self.iteration == NUM_ITERATIONS-1 { Duration::from_secs_f32(LONG_BREAK_DURATION_SECS) } else { Duration::from_secs_f32(SHORT_BREAK_DURATION_SECS) } + } else { + self.iteration = (self.iteration + 1) % NUM_ITERATIONS; + Duration::from_secs_f32(WORK_DURATION_SECS) + } + } + + fn notify(&self) { + if self.on_break { + Notification::new() + .summary("Break Complete") + .body("Click to dismiss") + .show().unwrap(); + } else { + Notification::new() + .summary(&format!("Pomodoro Complete ({}/{})", self.iteration + 1, NUM_ITERATIONS)) + .body("Click to dismiss") + .show().unwrap(); + } + } +} + +#[async_std::main] +async fn main() -> Result<()> { + let pomd_interface = PomdInterface::default(); + let pomd = pomd_interface.data.clone(); + let _connection = ConnectionBuilder::session()? + .name("dev.exvacuum.pomd")? + .serve_at("/dev/exvacuum/pomd", pomd_interface)? + .build() + .await?; + loop { + pomd.lock().unwrap().update(); + } +} |