diff options
author | Robin Krahl <robin.krahl@ireas.org> | 2019-01-08 03:16:20 +0000 |
---|---|---|
committer | Robin Krahl <robin.krahl@ireas.org> | 2019-01-08 04:54:20 +0100 |
commit | ec84c425282c3fd26f5e862b7864ad2ae7ec1e2e (patch) | |
tree | 347baad0fc42290ab5da2330d828f284d1ee8d88 /src/backends | |
parent | 1c76a540d647f351e27498e6f2135ff404853693 (diff) | |
download | dialog-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.rs | 85 | ||||
-rw-r--r-- | src/backends/mod.rs | 3 |
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<()>; } |