use async_std::task; use clap::{App, Arg, 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::path::{Path, PathBuf}; 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") .arg( Arg::with_name("alert") .short("a") .long("alert") .value_name("FILE") .takes_value(true) .help("Aloud Sound. (Supports WAV, MP3, Vorbis, FLAC)"), ), ) .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: PathBuf; if let Some(path) = args.value_of("alert") { audio_path = Path::new(path).to_path_buf(); } else { 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(); }