summaryrefslogtreecommitdiff
path: root/src/backends
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
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')
-rw-r--r--src/backends/dialog.rs85
-rw-r--r--src/backends/mod.rs3
2 files changed, 65 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(|_| ())
}
diff --git a/src/backends/mod.rs b/src/backends/mod.rs
index c316307..1abb8d1 100644
--- a/src/backends/mod.rs
+++ b/src/backends/mod.rs
@@ -17,6 +17,9 @@ use std::io::Result;
/// [`default_backend`]: ../function.default_backend.html
/// [`show_with`]: ../trait.DialogBox.html#method.show_with
pub trait Backend {
+ /// Shows the given input dialog and returns the input.
+ fn show_input(&self, input: &super::Input) -> Result<Option<String>>;
+
/// Shows the given message dialog.
fn show_message(&self, message: &super::Message) -> Result<()>;
}