diff options
Diffstat (limited to 'src/commands/util.rs')
-rw-r--r-- | src/commands/util.rs | 68 |
1 files changed, 67 insertions, 1 deletions
diff --git a/src/commands/util.rs b/src/commands/util.rs index 22ce5d4..9221030 100644 --- a/src/commands/util.rs +++ b/src/commands/util.rs @@ -8,13 +8,16 @@ // SPDX-License-Identifier: EPL-2.0 // +use std::io::Write; +use std::fmt::Display; use std::path::Path; -use anyhow::Error; use anyhow::Context; +use anyhow::Error; use anyhow::Result; use anyhow::anyhow; use clap::ArgMatches; +use itertools::Itertools; use log::{error, info, trace}; use regex::Regex; use tokio_stream::StreamExt; @@ -147,3 +150,66 @@ pub fn mk_package_name_regex(regex: &str) -> Result<Regex> { .with_context(|| anyhow!("Failed to build regex from '{}'", regex)) .map_err(Error::from) } + + +pub fn mk_header(vec: Vec<&str>) -> Vec<ascii_table::Column> { + vec.into_iter() + .map(|name| ascii_table::Column { + header: name.into(), + align: ascii_table::Align::Left, + ..Default::default() + }) + .collect() +} + +/// Display the passed data as nice ascii table, +/// or, if stdout is a pipe, print it nicely parseable +pub fn display_data<D: Display>( + headers: Vec<ascii_table::Column>, + data: Vec<Vec<D>>, + csv: bool, +) -> Result<()> { + if data.is_empty() { + return Ok(()) + } + + if csv { + use csv::WriterBuilder; + let mut wtr = WriterBuilder::new().from_writer(vec![]); + for record in data.into_iter() { + let r: Vec<String> = record.into_iter().map(|e| e.to_string()).collect(); + + wtr.write_record(&r)?; + } + + let out = std::io::stdout(); + let mut lock = out.lock(); + + wtr.into_inner() + .map_err(Error::from) + .and_then(|t| String::from_utf8(t).map_err(Error::from)) + .and_then(|text| writeln!(lock, "{}", text).map_err(Error::from)) + } else if atty::is(atty::Stream::Stdout) { + let mut ascii_table = ascii_table::AsciiTable { + columns: Default::default(), + max_width: terminal_size::terminal_size() + .map(|tpl| tpl.0 .0 as usize) // an ugly interface indeed! + .unwrap_or(80), + }; + + headers.into_iter().enumerate().for_each(|(i, c)| { + ascii_table.columns.insert(i, c); + }); + + ascii_table.print(data); + Ok(()) + } else { + let out = std::io::stdout(); + let mut lock = out.lock(); + for list in data { + writeln!(lock, "{}", list.iter().map(|d| d.to_string()).join(" "))?; + } + Ok(()) + } +} + |