Rework implementation method

This commit is contained in:
George Pollard 2019-08-24 17:31:50 +12:00
parent 12cedddd68
commit c67d4a6eff
No known key found for this signature in database
GPG Key ID: 6694D898AEB73984
2 changed files with 43 additions and 24 deletions

View File

@ -10,8 +10,11 @@ use prettytable::{color, Attr, Cell, Row, Table};
#[derive(Debug, new)] #[derive(Debug, new)]
pub struct TableView { pub struct TableView {
// List of header cell values:
headers: Vec<String>, headers: Vec<String>,
entries: Vec<Vec<String>>,
// List of rows of cells, each containing value and prettytable style-string:
entries: Vec<Vec<(String, &'static str)>>,
} }
impl TableView { impl TableView {
@ -41,21 +44,26 @@ impl TableView {
let mut entries = vec![]; let mut entries = vec![];
for (idx, value) in values.iter().enumerate() { for (idx, value) in values.iter().enumerate() {
let mut row: Vec<String> = match value { let mut row: Vec<(String, &'static str)> = match value {
Tagged { Tagged {
item: Value::Object(..), item: Value::Object(..),
.. ..
} => headers } => headers
.iter() .iter()
.enumerate() .enumerate()
.map(|(i, d)| value.get_data(d).borrow().format_leaf(Some(&headers[i]))) .map(|(i, d)| {
let data = value.get_data(d);
return (data.borrow().format_leaf(Some(&headers[i])), data.borrow().style_leaf());
})
.collect(), .collect(),
x => vec![x.format_leaf(None)], x => vec![(x.format_leaf(None), x.style_leaf())],
}; };
if values.len() > 1 { if values.len() > 1 {
row.insert(0, format!("{}", idx.to_string())); // Indices are black, bold, right-aligned:
row.insert(0, (format!("{}", idx.to_string()), "Fdbr"));
} }
entries.push(row); entries.push(row);
} }
@ -66,13 +74,15 @@ impl TableView {
} }
for head in 0..headers.len() { for head in 0..headers.len() {
let mut current_row_max = 0; let mut current_col_max = 0;
for row in 0..values.len() { for row in 0..values.len() {
if entries[row][head].len() > current_row_max { let value_length = entries[row][head].0.len();
current_row_max = entries[row][head].len(); if value_length > current_col_max {
current_col_max = value_length;
} }
} }
max_per_column.push(std::cmp::max(current_row_max, headers[head].len()));
max_per_column.push(std::cmp::max(current_col_max, headers[head].len()));
} }
// Different platforms want different amounts of buffer, not sure why // Different platforms want different amounts of buffer, not sure why
@ -88,9 +98,9 @@ impl TableView {
entries[row].truncate(max_num_of_columns); entries[row].truncate(max_num_of_columns);
} }
headers.push("...".to_string()); headers.push("".to_string());
for row in 0..entries.len() { for row in 0..entries.len() {
entries[row].push("...".to_string()); entries[row].push(("".to_string(), "c")); // ellipsis is centred
} }
} }
@ -167,19 +177,11 @@ impl TableView {
if max_per_column[head] > max_naive_column_width { if max_per_column[head] > max_naive_column_width {
headers[head] = fill(&headers[head], max_column_width); headers[head] = fill(&headers[head], max_column_width);
for row in 0..entries.len() { for row in 0..entries.len() {
entries[row][head] = fill(&entries[row][head], max_column_width); entries[row][head].0 = fill(&entries[row][head].0, max_column_width);
} }
} }
} }
// Paint the number column, if it exists
if entries.len() > 1 {
for row in 0..entries.len() {
entries[row][0] =
format!("{}", Color::Black.bold().paint(entries[row][0].to_string()));
}
}
Some(TableView { headers, entries }) Some(TableView { headers, entries })
} }
} }
@ -215,7 +217,7 @@ impl RenderView for TableView {
table.set_titles(Row::new(header)); table.set_titles(Row::new(header));
for row in &self.entries { for row in &self.entries {
table.add_row(Row::new(row.iter().map(|h| Cell::new(h)).collect())); table.add_row(Row::new(row.iter().map(|(v, s)| Cell::new(v).style_spec(s)).collect()));
} }
table.print_term(&mut *host.out_terminal()).unwrap(); table.print_term(&mut *host.out_terminal()).unwrap();

View File

@ -94,14 +94,14 @@ impl Primitive {
let byte = byte_unit::Byte::from_bytes(*b as u128); let byte = byte_unit::Byte::from_bytes(*b as u128);
if byte.get_bytes() == 0u128 { if byte.get_bytes() == 0u128 {
return " ".to_string(); return "".to_string();
} }
let byte = byte.get_appropriate_unit(false); let byte = byte.get_appropriate_unit(false);
match byte.get_unit() { match byte.get_unit() {
byte_unit::ByteUnit::B => format!("{:>5} B ", byte.get_value()), byte_unit::ByteUnit::B => format!("{} B ", byte.get_value()),
_ => format!("{:>8}", byte.format(1)), _ => format!("{}", byte.format(1)),
} }
} }
Primitive::Int(i) => format!("{}", i), Primitive::Int(i) => format!("{}", i),
@ -118,6 +118,16 @@ impl Primitive {
Primitive::Date(d) => format!("{}", d.humanize()), Primitive::Date(d) => format!("{}", d.humanize()),
} }
} }
pub fn style(&self) -> &'static str {
match self {
Primitive::Bytes(0) => "c", // centre 'missing' indicator
Primitive::Int(_) |
Primitive::Bytes(_) |
Primitive::Float(_) => "r",
_ => ""
}
}
} }
#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Clone, new, Serialize)] #[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Clone, new, Serialize)]
@ -459,6 +469,13 @@ impl Value {
} }
} }
crate fn style_leaf(&self) -> &'static str {
match self {
Value::Primitive(p) => p.style(),
_ => ""
}
}
#[allow(unused)] #[allow(unused)]
crate fn compare(&self, operator: &Operator, other: &Value) -> Result<bool, (String, String)> { crate fn compare(&self, operator: &Operator, other: &Value) -> Result<bool, (String, String)> {
match operator { match operator {