From 763219bc4331331351b4180d4775432e9e11f8b2 Mon Sep 17 00:00:00 2001
From: Robin Krahl <robin.krahl@ireas.org>
Date: Thu, 10 Sep 2020 13:34:46 +0200
Subject: Add is_tty field to Context

This patch adds the is_tty field to the Context struct that indicates
whether stdout is a TTY.  This allows us to use TTY features like moving
the cursor in our output.
---
 CHANGELOG.md     |  1 +
 Cargo.lock       | 28 ++++++++++++++++++++++++++++
 Cargo.toml       |  3 +++
 src/main.rs      | 13 +++++++++++--
 src/tests/mod.rs |  1 +
 5 files changed, 44 insertions(+), 2 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8672e03..3877847 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,7 @@ Unreleased
 ----------
 - Added the `fill` command that fills the SD card of a Nitrokey Storage device
   with random data
+  - Added the `termion` dependency in version `1.5.5`
 - Added SD card usage information to the output of the `status` command for
   Storage devices
 
diff --git a/Cargo.lock b/Cargo.lock
index 4af9f62..aad2667 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -207,6 +207,7 @@ dependencies = [
  "regex",
  "serde",
  "structopt",
+ "termion",
  "toml",
 ]
 
@@ -257,6 +258,12 @@ dependencies = [
  "autocfg",
 ]
 
+[[package]]
+name = "numtoa"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef"
+
 [[package]]
 name = "proc-macro-error"
 version = "1.0.2"
@@ -316,6 +323,15 @@ version = "0.1.57"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
 
+[[package]]
+name = "redox_termios"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
+dependencies = [
+ "redox_syscall",
+]
+
 [[package]]
 name = "redox_users"
 version = "0.3.4"
@@ -423,6 +439,18 @@ dependencies = [
  "syn",
 ]
 
+[[package]]
+name = "termion"
+version = "1.5.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c22cec9d8978d906be5ac94bceb5a010d885c626c4c8855721a4dbd20e3ac905"
+dependencies = [
+ "libc",
+ "numtoa",
+ "redox_syscall",
+ "redox_termios",
+]
+
 [[package]]
 name = "textwrap"
 version = "0.11.0"
diff --git a/Cargo.toml b/Cargo.toml
index fd057e1..ad85e4a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -61,6 +61,9 @@ features = ["derive"]
 version = "0.3.17"
 default-features = false
 
+[dependencies.termion]
+version = "1.5.5"
+
 [dependencies.toml]
 version = "0.5.6"
 
diff --git a/src/main.rs b/src/main.rs
index baad15c..1a2a3d3 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -98,6 +98,8 @@ pub struct Context<'io> {
   pub stdout: &'io mut dyn io::Write,
   /// The `Write` object used as standard error throughout the program.
   pub stderr: &'io mut dyn io::Write,
+  /// Whether `stdout` is a TTY.
+  pub is_tty: bool,
   /// The admin PIN, if provided through an environment variable.
   pub admin_pin: Option<ffi::OsString>,
   /// The user PIN, if provided through an environment variable.
@@ -118,7 +120,12 @@ pub struct Context<'io> {
 }
 
 impl<'io> Context<'io> {
-  fn from_env<O, E>(stdout: &'io mut O, stderr: &'io mut E, config: config::Config) -> Context<'io>
+  fn from_env<O, E>(
+    stdout: &'io mut O,
+    stderr: &'io mut E,
+    is_tty: bool,
+    config: config::Config,
+  ) -> Context<'io>
   where
     O: io::Write,
     E: io::Write,
@@ -126,6 +133,7 @@ impl<'io> Context<'io> {
     Context {
       stdout,
       stderr,
+      is_tty,
       admin_pin: env::var_os(NITROCLI_ADMIN_PIN),
       user_pin: env::var_os(NITROCLI_USER_PIN),
       new_admin_pin: env::var_os(NITROCLI_NEW_ADMIN_PIN),
@@ -154,8 +162,9 @@ fn main() {
 
   let rc = match config::Config::load() {
     Ok(config) => {
+      let is_tty = termion::is_tty(&stdout);
       let args = env::args().collect::<Vec<_>>();
-      let ctx = &mut Context::from_env(&mut stdout, &mut stderr, config);
+      let ctx = &mut Context::from_env(&mut stdout, &mut stderr, is_tty, config);
 
       run(ctx, args)
     }
diff --git a/src/tests/mod.rs b/src/tests/mod.rs
index e0a5b9a..1871f3c 100644
--- a/src/tests/mod.rs
+++ b/src/tests/mod.rs
@@ -99,6 +99,7 @@ impl Nitrocli {
     let ctx = &mut crate::Context {
       stdout: &mut stdout,
       stderr: &mut stderr,
+      is_tty: false,
       admin_pin: self.admin_pin.clone(),
       user_pin: self.user_pin.clone(),
       new_admin_pin: self.new_admin_pin.clone(),
-- 
cgit v1.2.3