From 04b4262cdf4bbb4e2698d8ce51a261bf294a2da3 Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Sat, 5 Sep 2020 13:18:41 +0200 Subject: Add --output-format argument This patch adds the --output-format argument that makes it possible to select a format for the data that nitrocli prints to stdout. Currently, the only supported format is text output, i. e. a human-readable representation. TODO: man page, changelog --- src/args.rs | 23 +++++++++++++++++++++++ src/config.rs | 5 +++++ src/output.rs | 41 ++++++++++++++++++++++++++++------------- 3 files changed, 56 insertions(+), 13 deletions(-) diff --git a/src/args.rs b/src/args.rs index f54025e..758af8c 100644 --- a/src/args.rs +++ b/src/args.rs @@ -16,6 +16,9 @@ pub struct Args { /// Disables the cache for all secrets. #[structopt(long, global = true)] pub no_cache: bool, + /// Selects the output format. + #[structopt(long, global = true, possible_values = &OutputFormat::all_str())] + pub output_format: Option, #[structopt(subcommand)] pub cmd: Command, } @@ -68,6 +71,26 @@ impl<'de> serde::Deserialize<'de> for DeviceModel { } } +Enum! { + /// The format for the nitrocli output. + OutputFormat, [ + Text => "text", + ] +} + +impl<'de> serde::Deserialize<'de> for OutputFormat { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + use serde::de::Error as _; + use std::str::FromStr as _; + + let s = String::deserialize(deserializer)?; + OutputFormat::from_str(&s).map_err(D::Error::custom) + } +} + Command! { /// A top-level command for nitrocli. Command, [ diff --git a/src/config.rs b/src/config.rs index aceda38..b96d071 100644 --- a/src/config.rs +++ b/src/config.rs @@ -32,6 +32,8 @@ pub struct Config { #[merge(strategy = merge::num::overwrite_zero)] #[serde(default)] pub verbosity: u8, + /// The output format. + pub output_format: Option, } impl Config { @@ -57,6 +59,9 @@ impl Config { if args.verbose > 0 { self.verbosity = args.verbose; } + if args.output_format.is_some() { + self.output_format = args.output_format; + } } } diff --git a/src/output.rs b/src/output.rs index 77fb93b..7c85a82 100644 --- a/src/output.rs +++ b/src/output.rs @@ -7,19 +7,28 @@ use std::fmt; +use crate::args; use crate::Context; /// A trait for objects that can be printed as nitrocli’s output. pub trait Output { - /// Formats this object as a string that can be printed to the standard output. - fn format(&self) -> anyhow::Result; + /// Formats this object using the given output format. + fn format(&self, format: args::OutputFormat) -> anyhow::Result; - /// Prints this object to the output set in the given context. + /// Prints this object to the output set in the given context using the output format set in the + /// context configuration. /// /// The default implementation for this method prints the return value of `format` to /// `ctx.stdout`. fn print(&self, ctx: &mut Context<'_>) -> anyhow::Result<()> { - println!(ctx, "{}", self.format()?.trim_end()).map_err(From::from) + println!( + ctx, + "{}", + self + .format(ctx.config.output_format.unwrap_or(args::OutputFormat::Text))? + .trim_end() + ) + .map_err(From::from) } } @@ -54,8 +63,10 @@ impl Value { } impl Output for Value { - fn format(&self) -> anyhow::Result { - Ok(self.0.to_string()) + fn format(&self, format: args::OutputFormat) -> anyhow::Result { + match format { + args::OutputFormat::Text => Ok(self.0.to_string()), + } } } @@ -77,13 +88,17 @@ impl Table { } impl Output for Table { - fn format(&self) -> anyhow::Result { - if self.items.is_empty() { - Ok(self.empty_message.clone()) - } else { - let headers = T::headers().into_iter().map(ToOwned::to_owned).collect(); - let values = self.items.iter().map(TableItem::values); - Ok(print_table(headers, values)) + fn format(&self, format: args::OutputFormat) -> anyhow::Result { + match format { + args::OutputFormat::Text => { + if self.items.is_empty() { + Ok(self.empty_message.clone()) + } else { + let headers = T::headers().into_iter().map(ToOwned::to_owned).collect(); + let values = self.items.iter().map(TableItem::values); + Ok(print_table(headers, values)) + } + } } } } -- cgit v1.2.1