mod interval; mod message; mod pid; mod pomodoro; mod ui; use std::process::ExitCode; use anyhow::{bail, Result}; use tokio::sync::broadcast::channel; use tokio::task::JoinSet; #[tokio::main(flavor = "current_thread")] async fn main() -> ExitCode { match main2().await { Ok(()) => ExitCode::SUCCESS, Err(e) => { eprintln!("{}", e.root_cause()); ExitCode::FAILURE } } } async fn main2() -> Result<()> { let pid = if let Some(pid) = pid::Pid::check_already_running() { bail!("already running (pid {})", pid.pid) } else { pid::Pid::create()? }; let result = run_all_tasks().await; ui::clear_terminal()?; pid.remove()?; result } async fn run_all_tasks() -> Result<()> { let (tx, rx) = channel::(10); let timer = pomodoro::Pomodoro::new(rx); let ui = ui::Ui::new(tx); let mut tasks = JoinSet::new(); tasks.spawn(timer.main_loop()); tasks.spawn(ui.main_loop()); while let Some(result) = tasks.join_next().await { result??; } Ok(()) }