use async_std::task; use clap::{App, ArgMatches, SubCommand}; use crossterm::{cursor, terminal::Clear, terminal::ClearType, QueueableCommand}; use domasi::pomodoro::{Alert, Clock, Config, Status}; use domasi::Pomodoro; use std::io::{stdout, Write}; use std::sync::mpsc::{channel, Receiver, Sender}; use std::thread; fn main() { let matches = App::new("Domasi") .version("0.1.0") .author("paoda ") .about("Yet another pomodoro timer.") .subcommand(SubCommand::with_name("start").about("Start the Pomodoro Timer")) .get_matches(); // match matches.subcommand() { // ("start", Some(sub_matches)) => start(sub_matches), // _ => {} // } if let ("start", Some(sub_matches)) = matches.subcommand() { start(sub_matches); } } pub fn start(_args: &ArgMatches) { let config = Config::default(); let audio_path = config.data_directory.join("sound/alert.ogg"); let default_device = rodio::default_output_device().unwrap(); let alert = Alert::new(&audio_path, &default_device); let mut pomodoro = Pomodoro::new(&alert); task::block_on(async { let (tx, rx): (Sender, Receiver) = channel(); thread::spawn(move || loop { if let Ok(status) = rx.recv() { loop { let (remaining, string) = Clock::get_formatted_string(status); print_overwrite(&string); // Super fun race condition that you gotta handle better :) if remaining < 1 { break; } thread::sleep(Clock::get_polling_interval()); } } }); pomodoro.start(config, tx).await; }); } fn print_overwrite(text: &str) { let mut stdout = stdout(); stdout.queue(Clear(ClearType::CurrentLine)).unwrap(); stdout.queue(cursor::SavePosition).unwrap(); stdout.write_all(text.as_bytes()).unwrap(); stdout.queue(cursor::RestorePosition).unwrap(); stdout.flush().unwrap(); }