Compare commits
3 Commits
0c954962cc
...
56beda6840
Author | SHA1 | Date |
---|---|---|
Moritz Böhme | 56beda6840 | |
Moritz Böhme | 61b7bd447d | |
Moritz Böhme | 98acf3c74e |
41
src/cli.rs
41
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<UnixStream> {
|
||||
|
|
|
@ -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 {
|
||||
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())),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,9 +78,14 @@ impl Pomodoro {
|
|||
};
|
||||
self.status = match self.status {
|
||||
Status::Working => {
|
||||
if self.pauses == self.pauses_till_long {
|
||||
self.pauses = 0;
|
||||
Status::LongPause
|
||||
} else {
|
||||
self.pauses += 1;
|
||||
Status::Pausing
|
||||
}
|
||||
}
|
||||
_ => Status::Working,
|
||||
};
|
||||
self.timer = Timer::new(self.status.to_string().into_boxed_str(), duration);
|
||||
|
|
Loading…
Reference in New Issue