diff options
author | Robin Krahl <robin.krahl@ireas.org> | 2019-01-08 02:11:55 +0000 |
---|---|---|
committer | Robin Krahl <robin.krahl@ireas.org> | 2019-01-08 04:54:00 +0100 |
commit | a0b0a3c6a57097d56c5c471e5cb72bbde8198da8 (patch) | |
tree | bc91299159628f89594053aedcef3eaa71497413 /src/backends | |
parent | 31e1410bf3299301879171d5677f69925828844c (diff) | |
download | dialog-rs-a0b0a3c6a57097d56c5c471e5cb72bbde8198da8.tar.gz dialog-rs-a0b0a3c6a57097d56c5c471e5cb72bbde8198da8.tar.bz2 |
Implement message boxes using the dialog backend
This patch adds a first dialog box type, message boxes, and a first
backend, the dialog(1) tool. It does not yet address the problems of
output handling and backend selection.
Diffstat (limited to 'src/backends')
-rw-r--r-- | src/backends/dialog.rs | 90 | ||||
-rw-r--r-- | src/backends/mod.rs | 22 |
2 files changed, 112 insertions, 0 deletions
diff --git a/src/backends/dialog.rs b/src/backends/dialog.rs new file mode 100644 index 0000000..b448c05 --- /dev/null +++ b/src/backends/dialog.rs @@ -0,0 +1,90 @@ +// Copyright (C) 2019 Robin Krahl <robin.krahl@ireas.org> +// SPDX-License-Identifier: MIT + +use std::io; +use std::io::Result; +use std::process; + +use crate::Message; + +/// The `dialog` backend. +/// +/// This backend uses the external `dialog` program (not to be confused with this crate also called +/// `dialog`) to display text-based dialog boxes in the terminal. +#[derive(Debug)] +pub struct Dialog { + backtitle: Option<String>, + width: String, + height: String, +} + +impl Dialog { + /// Creates a new `Dialog` instance without configuration. + pub fn new() -> Dialog { + Dialog { + backtitle: None, + height: "0".to_string(), + width: "0".to_string(), + } + } + + fn execute(&self, args: Vec<&str>) -> Result<process::ExitStatus> { + 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).status() + } + + /// Sets the backtitle for the dialog boxes. + /// + /// The backtitle is displayed on the backdrop, at the top of the screen. + pub fn set_backtitle(&mut self, backtitle: impl Into<String>) { + self.backtitle = Some(backtitle.into()); + } + + /// Sets the height of the dialog boxes. + /// + /// The height is given in characters. The actual height of the dialog box might be higher + /// than the given height if the content would not fit otherwise. The default height is zero. + pub fn set_height(&mut self, height: u32) { + self.height = height.to_string(); + } + + /// Sets the width of the dialog boxes. + /// + /// The width is given in characters. The actual width of the dialog box might be higher than + /// the given width if the content would not fit otherwise. The default width is zero. + pub fn set_width(&mut self, width: u32) { + self.width = width.to_string(); + } + + fn show_box(&self, args: Vec<&str>, title: &Option<String>) -> Result<process::ExitStatus> { + let mut args = args; + if let Some(ref title) = title { + args.insert(0, "--title"); + args.insert(1, title); + } + args.push(&self.height); + args.push(&self.width); + self.execute(args) + } +} + +fn require_success(status: process::ExitStatus) -> Result<()> { + if status.success() { + Ok(()) + } else { + Err(io::Error::new(io::ErrorKind::Other, "dialog failed")) + } +} + +impl super::Backend for Dialog { + fn show_message(&self, message: &Message) -> Result<()> { + let args = vec!["--msgbox", &message.text]; + self.show_box(args, &message.title) + .and_then(require_success) + } +} diff --git a/src/backends/mod.rs b/src/backends/mod.rs new file mode 100644 index 0000000..c316307 --- /dev/null +++ b/src/backends/mod.rs @@ -0,0 +1,22 @@ +// Copyright (C) 2019 Robin Krahl <robin.krahl@ireas.org> +// SPDX-License-Identifier: MIT + +mod dialog; + +pub use crate::backends::dialog::Dialog; + +use std::io::Result; + +/// A dialog backend. +/// +/// A dialog backend is a program that can be used to display dialog boxes. Use the +/// [`default_backend`][] function to create a new instance of the default backend, or choose a +/// backend and create an instance manually. To use a backend, pass it to the [`show_with`][] +/// method of a dialog box. +/// +/// [`default_backend`]: ../function.default_backend.html +/// [`show_with`]: ../trait.DialogBox.html#method.show_with +pub trait Backend { + /// Shows the given message dialog. + fn show_message(&self, message: &super::Message) -> Result<()>; +} |