diff --git a/src/cli.rs b/src/cli.rs index 5053962..fb498bc 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -5,10 +5,9 @@ use std::net::Shutdown; use std::os::unix::net::UnixStream; use std::time::Duration; -#[derive(Debug, Parser)] +#[derive(Parser)] #[command(name = "timers")] -#[command(about = "A advanced timer daemon/cli.", long_about = None)] -#[command(arg_required_else_help = true)] +/// A advanced timer daemon/cli. pub struct Cli { #[command(subcommand)] pub command: Command, @@ -19,35 +18,67 @@ pub struct Cli { #[derive(Debug, Subcommand)] pub enum Command { + /// Run as daemon + #[clap(visible_alias="d")] Daemon { + /// do not send notifications #[arg(short, long)] - notify: bool, + no_notify: bool, }, + /// Add a timer + #[clap(visible_alias="a")] Add { + /// name of the timer name: String, + /// duration of the timer duration: humantime::Duration, }, + /// List timers + #[clap(visible_alias="l")] List, + /// Remove a timer + #[clap(visible_alias="r")] Remove { + /// name of the timer to remove name: String, }, + /// Pomodoro specific command #[command(subcommand)] + #[clap(visible_alias="p")] Pomodoro(PomodoroCommand) } #[derive(Debug, Subcommand)] pub enum PomodoroCommand { + /// Start pomodoro + #[clap(visible_alias="s")] Start { + /// duration to work for + #[arg(long)] #[clap(default_value_t = Duration::from_secs(25 * 60).into())] work: humantime::Duration, + + /// duration for short pauses + #[arg(long)] #[clap(default_value_t = Duration::from_secs(5 * 60).into())] pause: humantime::Duration, + + /// duration for long pauses + #[arg(long)] #[clap(default_value_t = Duration::from_secs(10 * 60).into())] long_pause: humantime::Duration, + + /// number of short pauses till long pause + #[arg(long)] #[clap(default_value_t = 3)] pauses_till_long: u64, }, - Stop, + /// Stop the pomodoro + #[clap(visible_alias="p")] + Remove, + /// List the pomodoro settings and remaining duration + #[clap(visible_alias="l")] + List, } fn get_stream(socket_path: &String) -> Result { diff --git a/src/daemon.rs b/src/daemon.rs index 95b6962..41fa1cd 100644 --- a/src/daemon.rs +++ b/src/daemon.rs @@ -22,33 +22,34 @@ pub enum Command { long_pause: Duration, pauses_till_long: u64, }, - PomodoroStop + PomodoroRemove, + PomodoroList, } #[derive(Debug, Serialize, Deserialize)] pub enum Answer { Ok, - Timers(Vec, Option), + Timers(Vec), + Pomodoro(Option), } impl Display for Answer { fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> { match self { Answer::Ok => write!(f, "Ok"), - Answer::Timers(timers, pomodoro) => { + Answer::Timers(timers) => { if timers.is_empty() { - writeln!(f, "No timers running.")?; + writeln!(f, "No timers running.") } else { let strings: Vec = timers.iter().map(|timer| timer.to_string()).collect(); - writeln!(f, "{}", strings.join("\n"))?; - }; - - match pomodoro { - Some(p) => write!(f, "{}", p), - None => write!(f, "No pomodoro running."), + writeln!(f, "{}", strings.join("\n")) } } + Answer::Pomodoro(pomodoro) => match pomodoro { + Some(p) => write!(f, "{}", p), + None => write!(f, "No pomodoro running."), + }, } } } @@ -69,7 +70,7 @@ pub struct Daemon { } impl Daemon { - pub fn new(socket_path: String, notify: bool) -> anyhow::Result { + pub fn new(socket_path: String, no_notify: bool) -> anyhow::Result { let path = std::path::Path::new(&socket_path); if path.exists() { std::fs::remove_file(path) @@ -81,7 +82,7 @@ impl Daemon { listener, timers: Vec::new(), pomodoro: None, - notify, + notify: !no_notify, }) } @@ -92,7 +93,7 @@ impl Daemon { fn handle_command(&mut self, command: Command) -> Result { println!("Received command {:?}", command); match command { - Command::List => Ok(Answer::Timers(self.timers.clone(), self.pomodoro.clone())), + Command::List => Ok(Answer::Timers(self.timers.clone())), Command::Add(name, duration) => { if self.has_timer(&name) { return Err(AnswerErr::TimerAlreadyExist(name)); @@ -145,10 +146,11 @@ impl Daemon { self.pomodoro = Some(Pomodoro::new(work, pause, long_pause, pauses_till_long)); Ok(Answer::Ok) } - Command::PomodoroStop => { + Command::PomodoroRemove => { self.pomodoro = None; Ok(Answer::Ok) - }, + } + Command::PomodoroList => Ok(Answer::Pomodoro(self.pomodoro.clone())), } } diff --git a/src/main.rs b/src/main.rs index 4e81bdd..72bfe2d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,7 +12,7 @@ use cli::PomodoroCommand; fn main() -> Result<()> { let args = Cli::parse(); let daemon_command = match args.command { - CliCommand::Daemon { notify } => return Daemon::new(args.socket, notify)?.run(), + CliCommand::Daemon { no_notify } => return Daemon::new(args.socket, no_notify)?.run(), CliCommand::Add { name, duration } => { DaemonCommand::Add(name.into_boxed_str(), duration.into()) } @@ -30,7 +30,8 @@ fn main() -> Result<()> { long_pause: long_pause.into(), pauses_till_long, }, - PomodoroCommand::Stop => DaemonCommand::PomodoroStop, + PomodoroCommand::Remove => DaemonCommand::PomodoroRemove, + PomodoroCommand::List => DaemonCommand::PomodoroList, }, }; send_command(&args.socket, daemon_command) diff --git a/src/pomodoro.rs b/src/pomodoro.rs index da78e06..1bc2929 100644 --- a/src/pomodoro.rs +++ b/src/pomodoro.rs @@ -39,9 +39,9 @@ enum Status { impl Display for Status { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - Status::Working => write!(f, "pomodoro work"), - Status::Pausing => write!(f, "pomodoro pause"), - Status::LongPause => write!(f, "pomodoro long pause"), + Status::Working => write!(f, "work"), + Status::Pausing => write!(f, "pause"), + Status::LongPause => write!(f, "long pause"), } } } @@ -78,8 +78,13 @@ impl Pomodoro { }; self.status = match self.status { Status::Working => { - self.pauses += 1; - Status::Pausing + if self.pauses == self.pauses_till_long { + self.pauses = 0; + Status::LongPause + } else { + self.pauses += 1; + Status::Pausing + } } _ => Status::Working, };