Read alarm times from stdin.
This commit is contained in:
parent
d0aa9f7a4f
commit
3039af5aee
3 changed files with 65 additions and 32 deletions
66
src/alarm.rs
66
src/alarm.rs
|
@ -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
|
||||
}
|
||||
|
||||
|
|
21
src/lib.rs
21
src/lib.rs
|
@ -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
|
||||
|
|
10
src/main.rs
10
src/main.rs
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue