Compare commits

..

3 Commits

Author SHA1 Message Date
Moritz Böhme 56beda6840
fix: pauses not resetting 2023-07-29 16:11:25 +02:00
Moritz Böhme 61b7bd447d
feat: add command to list pomodoro 2023-07-29 16:02:42 +02:00
Moritz Böhme 98acf3c74e
feat: add documentation 2023-07-29 15:59:33 +02:00
4 changed files with 66 additions and 27 deletions

View File

@ -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<UnixStream> {

View File

@ -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<Timer>, Option<Pomodoro>),
Timers(Vec<Timer>),
Pomodoro(Option<Pomodoro>),
}
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<String> =
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<Self> {
pub fn new(socket_path: String, no_notify: bool) -> anyhow::Result<Self> {
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<Answer, AnswerErr> {
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())),
}
}

View File

@ -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)

View File

@ -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,
};