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();
|
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.
|
// Execute the command given on the command line.
|
||||||
pub fn exec_command(config: &Config, elapsed: u32, label: &String) -> Option<Child> {
|
pub fn exec_command(command: &Vec<String>, elapsed: u32, label: &String) -> Option<Child> {
|
||||||
let mut args: Vec<String> = Vec::new();
|
let time = if elapsed < 3600 {
|
||||||
let time: String;
|
format!("{:02}:{:02}", elapsed / 60, elapsed % 60)
|
||||||
|
|
||||||
if elapsed < 3600 {
|
|
||||||
time = format!("{:02}:{:02}", elapsed / 60, elapsed % 60);
|
|
||||||
} else {
|
} 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 {
|
match Command::new(&command[0])
|
||||||
// Replace every occurrence of "{}".
|
.args(args)
|
||||||
args.reserve_exact(command.len());
|
.stdout(Stdio::null())
|
||||||
for s in command {
|
.stdin(Stdio::null())
|
||||||
args.push(s.replace("{t}", &time).replace("{l}", &label));
|
.spawn() {
|
||||||
}
|
Ok(child) => Some(child),
|
||||||
|
Err(error) => {
|
||||||
match Command::new(&command[0]).args(&args[1..])
|
eprintln!("Error: Could not execute command. ({})", error);
|
||||||
.stdout(Stdio::null()).stdin(Stdio::null()).spawn() {
|
None
|
||||||
Ok(child) => return Some(child),
|
|
||||||
Err(error) => {
|
|
||||||
eprintln!("Error: Could not execute command. ({})", error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
21
src/lib.rs
21
src/lib.rs
|
@ -38,6 +38,7 @@ pub fn run(
|
||||||
let mut clock = Clock::new(&config);
|
let mut clock = Clock::new(&config);
|
||||||
let mut countdown = Countdown::new();
|
let mut countdown = Countdown::new();
|
||||||
let mut buffer = Buffer::new();
|
let mut buffer = Buffer::new();
|
||||||
|
|
||||||
let async_stdin = termion::async_stdin();
|
let async_stdin = termion::async_stdin();
|
||||||
let mut input_keys = async_stdin.keys();
|
let mut input_keys = async_stdin.keys();
|
||||||
let stdout = std::io::stdout();
|
let stdout = std::io::stdout();
|
||||||
|
@ -119,19 +120,17 @@ pub fn run(
|
||||||
write!(stdout, "{}", 0x07 as char)?;
|
write!(stdout, "{}", 0x07 as char)?;
|
||||||
layout.force_redraw = true;
|
layout.force_redraw = true;
|
||||||
|
|
||||||
// Run command if configured.
|
match config.command {
|
||||||
if config.command.is_some() {
|
// Run command if configured and no command is running.
|
||||||
if spawned.is_none() {
|
Some(ref command) if spawned.is_none() => {
|
||||||
*spawned = exec_command(&config, time, &label);
|
*spawned = exec_command(command, time, &label);
|
||||||
} else {
|
},
|
||||||
// The last command is still running.
|
// Last command is still running.
|
||||||
eprintln!("Not executing command, as its predecessor is still running");
|
Some(_) => eprintln!("Not executing command, as its predecessor is still running"),
|
||||||
}
|
None => (),
|
||||||
}
|
}
|
||||||
// Quit if configured.
|
// Quit if configured.
|
||||||
if config.quit && alarm_roster.idle() {
|
if config.quit && alarm_roster.idle() { break };
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear the window and redraw menu bar, alarm roster and buffer if
|
// 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);
|
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.
|
// Holds spawned child process if any.
|
||||||
let mut spawned: Option<process::Child> = None;
|
let mut spawned: Option<process::Child> = None;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue