aboutsummaryrefslogtreecommitdiff
path: root/src/backends/dialog.rs
diff options
context:
space:
mode:
authorRobin Krahl <robin.krahl@ireas.org>2019-01-08 03:16:20 +0000
committerRobin Krahl <robin.krahl@ireas.org>2019-01-08 04:54:20 +0100
commitec84c425282c3fd26f5e862b7864ad2ae7ec1e2e (patch)
tree347baad0fc42290ab5da2330d828f284d1ee8d88 /src/backends/dialog.rs
parent1c76a540d647f351e27498e6f2135ff404853693 (diff)
downloaddialog-rs-ec84c425282c3fd26f5e862b7864ad2ae7ec1e2e.tar.gz
dialog-rs-ec84c425282c3fd26f5e862b7864ad2ae7ec1e2e.tar.bz2
Add input dialog boxes
This patch implements input dialog boxes. This required some refactoring in the dialog backend to allow additional arguments after the width and the height.
Diffstat (limited to 'src/backends/dialog.rs')
-rw-r--r--src/backends/dialog.rs85
1 files changed, 62 insertions, 23 deletions
diff --git a/src/backends/dialog.rs b/src/backends/dialog.rs
index d50be43..8cde8cc 100644
--- a/src/backends/dialog.rs
+++ b/src/backends/dialog.rs
@@ -5,7 +5,7 @@ use std::io;
use std::io::Result;
use std::process;
-use crate::Message;
+use crate::{Input, Message};
/// The `dialog` backend.
///
@@ -28,20 +28,6 @@ impl Dialog {
}
}
- fn execute(&self, args: Vec<&str>) -> Result<process::Output> {
- let mut args = args;
- if let Some(ref backtitle) = self.backtitle {
- args.insert(0, "--backtitle");
- args.insert(1, backtitle);
- }
- println!("{:?}", args);
- process::Command::new("dialog")
- .args(args)
- .stdin(process::Stdio::inherit())
- .stdout(process::Stdio::inherit())
- .output()
- }
-
/// Sets the backtitle for the dialog boxes.
///
/// The backtitle is displayed on the backdrop, at the top of the screen.
@@ -65,15 +51,31 @@ impl Dialog {
self.width = width.to_string();
}
- fn show_box(&self, args: Vec<&str>, title: &Option<String>) -> Result<process::Output> {
- let mut args = args;
+ fn execute(
+ &self,
+ args: Vec<&str>,
+ post_args: Vec<&str>,
+ title: &Option<String>,
+ ) -> Result<process::Output> {
+ let mut command = process::Command::new("dialog");
+ command.stdin(process::Stdio::inherit());
+ command.stdout(process::Stdio::inherit());
+
+ if let Some(ref backtitle) = self.backtitle {
+ command.arg("--backtitle");
+ command.arg(backtitle);
+ }
if let Some(ref title) = title {
- args.insert(0, "--title");
- args.insert(1, title);
+ command.arg("--title");
+ command.arg(title);
}
- args.push(&self.height);
- args.push(&self.width);
- self.execute(args)
+
+ command.args(args);
+ command.arg(&self.height);
+ command.arg(&self.width);
+ command.args(post_args);
+
+ command.output()
}
}
@@ -85,10 +87,47 @@ fn require_success(status: process::ExitStatus) -> Result<()> {
}
}
+fn get_stderr(output: process::Output) -> Result<Option<String>> {
+ if output.status.success() {
+ String::from_utf8(output.stderr)
+ .map(|s| Some(s))
+ .map_err(|_| {
+ io::Error::new(io::ErrorKind::Other, "Input contained invalid UTF-8 bytes")
+ })
+ } else {
+ if let Some(code) = output.status.code() {
+ match code {
+ 0 => Ok(None),
+ 1 => Ok(None),
+ -1 => Ok(None),
+ _ => Err(io::Error::new(
+ io::ErrorKind::Other,
+ "Could not execute dialog",
+ )),
+ }
+ } else {
+ Err(io::Error::new(
+ io::ErrorKind::Other,
+ "dialog was terminated by a signal",
+ ))
+ }
+ }
+}
+
impl super::Backend for Dialog {
+ fn show_input(&self, input: &Input) -> Result<Option<String>> {
+ let args = vec!["--inputbox", &input.text];
+ let mut post_args: Vec<&str> = Vec::new();
+ if let Some(ref default) = input.default {
+ post_args.push(default);
+ }
+ self.execute(args, post_args, &input.title)
+ .and_then(get_stderr)
+ }
+
fn show_message(&self, message: &Message) -> Result<()> {
let args = vec!["--msgbox", &message.text];
- self.show_box(args, &message.title)
+ self.execute(args, vec![], &message.title)
.and_then(|output| require_success(output.status))
.map(|_| ())
}