Read alarm times from stdin.

This commit is contained in:
shy 2021-04-14 18:09:45 +02:00
parent d0aa9f7a4f
commit 3039af5aee
3 changed files with 65 additions and 32 deletions

View file

@ -316,34 +316,58 @@ impl AlarmRoster {
alarm.reset();
}
}
// Read alarm times from stdin.
pub fn from_stdin(&mut self, stdin: std::io::Stdin)
-> Result<(), String>
{
let mut buffer = String::new();
loop {
match stdin.read_line(&mut buffer) {
Ok(0) => break, // EOF.
Ok(1) => continue, // Empty (newline only).
Ok(_) => (),
Err(e) => return Err(e.to_string()),
}
// Strip newline.
buffer.retain(|c| c != '\n');
// Ignore lines containing only white spaces.
if buffer.contains(|c: char| !c.is_whitespace()) {
if let Err(e) = self.add(&buffer) {
return Err(e.to_string());
}
}
buffer.clear();
}
Ok(())
}
}
// Execute the command given on the command line.
pub fn exec_command(config: &Config, elapsed: u32, label: &String) -> Option<Child> {
let mut args: Vec<String> = Vec::new();
let time: String;
if elapsed < 3600 {
time = format!("{:02}:{:02}", elapsed / 60, elapsed % 60);
pub fn exec_command(command: &Vec<String>, elapsed: u32, label: &String) -> Option<Child> {
let time = if elapsed < 3600 {
format!("{:02}:{:02}", elapsed / 60, elapsed % 60)
} else {
time = format!("{:02}:{:02}:{:02}", elapsed /3600, (elapsed / 60) % 60, elapsed % 60);
format!("{:02}:{:02}:{:02}", elapsed /3600, (elapsed / 60) % 60, elapsed % 60)
};
let mut args: Vec<String> = Vec::new();
// Build vector of command line arguments. Replace every occurrence of
// "{t}" and "{l}".
for s in command.iter().skip(1) {
args.push(s.replace("{t}", &time).replace("{l}", &label));
}
if let Some(command) = &config.command {
// Replace every occurrence of "{}".
args.reserve_exact(command.len());
for s in command {
args.push(s.replace("{t}", &time).replace("{l}", &label));
}
match Command::new(&command[0]).args(&args[1..])
.stdout(Stdio::null()).stdin(Stdio::null()).spawn() {
Ok(child) => return Some(child),
Err(error) => {
eprintln!("Error: Could not execute command. ({})", error);
}
match Command::new(&command[0])
.args(args)
.stdout(Stdio::null())
.stdin(Stdio::null())
.spawn() {
Ok(child) => Some(child),
Err(error) => {
eprintln!("Error: Could not execute command. ({})", error);
None
}
}
None
}

View file

@ -38,6 +38,7 @@ pub fn run(
let mut clock = Clock::new(&config);
let mut countdown = Countdown::new();
let mut buffer = Buffer::new();
let async_stdin = termion::async_stdin();
let mut input_keys = async_stdin.keys();
let stdout = std::io::stdout();
@ -119,19 +120,17 @@ pub fn run(
write!(stdout, "{}", 0x07 as char)?;
layout.force_redraw = true;
// Run command if configured.
if config.command.is_some() {
if spawned.is_none() {
*spawned = exec_command(&config, time, &label);
} else {
// The last command is still running.
eprintln!("Not executing command, as its predecessor is still running");
}
match config.command {
// Run command if configured and no command is running.
Some(ref command) if spawned.is_none() => {
*spawned = exec_command(command, time, &label);
},
// Last command is still running.
Some(_) => eprintln!("Not executing command, as its predecessor is still running"),
None => (),
}
// Quit if configured.
if config.quit && alarm_roster.idle() {
break;
}
if config.quit && alarm_roster.idle() { break };
}
// Clear the window and redraw menu bar, alarm roster and buffer if

View file

@ -12,6 +12,16 @@ fn main() {
process::exit(1);
});
// Read alarm times from stdin if stdin not a tty.
let stdin = std::io::stdin();
if !termion::is_tty(&stdin) {
stdin.lock();
if let Err(e) = alarm_roster.from_stdin(stdin) {
eprintln!("Error while reading alarm times from stdin. ({})", e);
process::exit(1);
}
}
// Holds spawned child process if any.
let mut spawned: Option<process::Child> = None;