From 18e39343addb3deb197e644889c88f692a456b11 Mon Sep 17 00:00:00 2001 From: Jonathan Turner Date: Fri, 21 Jun 2019 16:20:06 +1200 Subject: [PATCH] Add vertical table view --- src/cli.rs | 2 + src/commands.rs | 2 + src/commands/table.rs | 16 ++++++++ src/commands/vtable.rs | 16 ++++++++ src/format.rs | 2 + src/format/table.rs | 5 --- src/format/vtable.rs | 84 ++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 122 insertions(+), 5 deletions(-) create mode 100644 src/commands/table.rs create mode 100644 src/commands/vtable.rs create mode 100644 src/format/vtable.rs diff --git a/src/cli.rs b/src/cli.rs index 868ccaf739..1dbba22c02 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -85,7 +85,9 @@ pub async fn cli() -> Result<(), Box> { sink("autoview", autoview::autoview), sink("clip", clip::clip), sink("save", save::save), + sink("table", table::table), sink("tree", tree::tree), + sink("vtable", vtable::vtable), ]); } diff --git a/src/commands.rs b/src/commands.rs index 71877da632..2923d449ff 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -28,6 +28,7 @@ crate mod sort_by; crate mod split_column; crate mod split_row; crate mod sysinfo; +crate mod table; crate mod to_array; crate mod to_ini; crate mod to_json; @@ -35,6 +36,7 @@ crate mod to_toml; crate mod tree; crate mod trim; crate mod view; +crate mod vtable; crate mod where_; crate use command::command; diff --git a/src/commands/table.rs b/src/commands/table.rs new file mode 100644 index 0000000000..d8e3ca7f2a --- /dev/null +++ b/src/commands/table.rs @@ -0,0 +1,16 @@ +use crate::commands::command::SinkCommandArgs; +use crate::errors::ShellError; +use crate::format::TableView; +use crate::prelude::*; + +pub fn table(args: SinkCommandArgs) -> Result<(), ShellError> { + if args.input.len() > 0 { + let mut host = args.ctx.host.lock().unwrap(); + let view = TableView::from_list(&args.input); + if let Some(view) = view { + handle_unexpected(&mut *host, |host| crate::format::print_view(&view, host)); + } + } + + Ok(()) +} diff --git a/src/commands/vtable.rs b/src/commands/vtable.rs new file mode 100644 index 0000000000..827170a2f0 --- /dev/null +++ b/src/commands/vtable.rs @@ -0,0 +1,16 @@ +use crate::commands::command::SinkCommandArgs; +use crate::errors::ShellError; +use crate::format::VTableView; +use crate::prelude::*; + +pub fn vtable(args: SinkCommandArgs) -> Result<(), ShellError> { + if args.input.len() > 0 { + let mut host = args.ctx.host.lock().unwrap(); + let view = VTableView::from_list(&args.input); + if let Some(view) = view { + handle_unexpected(&mut *host, |host| crate::format::print_view(&view, host)); + } + } + + Ok(()) +} diff --git a/src/format.rs b/src/format.rs index 9215c18824..53df2db863 100644 --- a/src/format.rs +++ b/src/format.rs @@ -3,6 +3,7 @@ crate mod generic; crate mod list; crate mod table; crate mod tree; +crate mod vtable; use crate::prelude::*; @@ -10,6 +11,7 @@ crate use entries::EntriesView; crate use generic::GenericView; crate use table::TableView; crate use tree::TreeView; +crate use vtable::VTableView; crate trait RenderView { fn render_view(&self, host: &mut dyn Host) -> Result<(), ShellError>; diff --git a/src/format/table.rs b/src/format/table.rs index a1530f0922..8a62b53a0c 100644 --- a/src/format/table.rs +++ b/src/format/table.rs @@ -6,11 +6,6 @@ use prettytable::format::{FormatBuilder, LinePosition, LineSeparator}; use prettytable::{color, Attr, Cell, Row, Table}; -// An entries list is printed like this: -// -// name : ... -// name2 : ... -// another_name : ... #[derive(new)] pub struct TableView { headers: Vec, diff --git a/src/format/vtable.rs b/src/format/vtable.rs new file mode 100644 index 0000000000..86ddd62df7 --- /dev/null +++ b/src/format/vtable.rs @@ -0,0 +1,84 @@ +use crate::format::RenderView; +use crate::object::{DescriptorName, Value}; +use crate::prelude::*; +use derive_new::new; +use prettytable::format::{FormatBuilder, LinePosition, LineSeparator}; + +use prettytable::{color, Attr, Cell, Row, Table}; + +#[derive(new)] +pub struct VTableView { + entries: Vec>, +} + +impl VTableView { + pub fn from_list(values: &[Value]) -> Option { + if values.len() == 0 { + return None; + } + + let item = &values[0]; + let headers = item.data_descriptors(); + + if headers.len() == 0 { + return None; + } + + let mut entries = vec![]; + + for header in headers { + let mut row = vec![]; + + if let DescriptorName::String(s) = &header.name { + row.push(s.clone()); + } else { + row.push("value".to_string()); + } + for value in values { + row.push(value.get_data(&header).borrow().format_leaf(Some(&header))); + } + entries.push(row); + } + + Some(VTableView { entries }) + } +} + +impl RenderView for VTableView { + fn render_view(&self, host: &mut dyn Host) -> Result<(), ShellError> { + if self.entries.len() == 0 { + return Ok(()); + } + + let mut table = Table::new(); + + let fb = FormatBuilder::new() + .separator(LinePosition::Top, LineSeparator::new('-', '+', ' ', ' ')) + .separator(LinePosition::Bottom, LineSeparator::new('-', '+', ' ', ' ')) + .column_separator('|') + .padding(1, 1); + + table.set_format(fb.build()); + + for row in &self.entries { + table.add_row(Row::new( + row.iter() + .enumerate() + .map(|(idx, h)| { + if idx == 0 { + Cell::new(h) + .with_style(Attr::ForegroundColor(color::GREEN)) + .with_style(Attr::Bold) + } else { + Cell::new(h) + } + }) + .collect(), + )); + } + + table.print_term(&mut *host.out_terminal()).unwrap(); + + Ok(()) + } +}