make grouped table output more readable

This commit is contained in:
Nikolas Schmidt-Voigt 2021-07-30 22:49:02 +02:00
parent ad97302723
commit 964458007e
4 changed files with 106 additions and 43 deletions

45
Cargo.lock generated
View file

@ -11,15 +11,6 @@ dependencies = [
"winapi",
]
[[package]]
name = "ansi_term"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
dependencies = [
"winapi",
]
[[package]]
name = "anyhow"
version = "1.0.42"
@ -47,10 +38,10 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
name = "bartib"
version = "0.1.0"
dependencies = [
"ansi_term 0.12.1",
"anyhow",
"chrono",
"clap",
"nu-ansi-term",
"thiserror",
]
@ -79,7 +70,7 @@ version = "2.33.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
dependencies = [
"ansi_term 0.11.0",
"ansi_term",
"atty",
"bitflags",
"strsim",
@ -88,6 +79,12 @@ dependencies = [
"vec_map",
]
[[package]]
name = "either"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
[[package]]
name = "hermit-abi"
version = "0.1.18"
@ -97,12 +94,32 @@ dependencies = [
"libc",
]
[[package]]
name = "itertools"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf"
dependencies = [
"either",
]
[[package]]
name = "libc"
version = "0.2.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c"
[[package]]
name = "nu-ansi-term"
version = "0.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cccf5ce0705f83c8afb776d00fe071ab994148efdd8e060909c6614b0fe740af"
dependencies = [
"itertools",
"overload",
"winapi",
]
[[package]]
name = "num-integer"
version = "0.1.44"
@ -122,6 +139,12 @@ dependencies = [
"autocfg",
]
[[package]]
name = "overload"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
[[package]]
name = "proc-macro2"
version = "1.0.24"

View file

@ -11,4 +11,4 @@ chrono = "0.4"
clap = "~2.33"
thiserror = "1.0"
anyhow = "1.0.42"
ansi_term = "0.12.1"
nu-ansi-term = "0.34.0"

View file

@ -1,4 +1,4 @@
use ansi_term::Colour;
use nu_ansi_term::Color;
use chrono::NaiveDate;
use std::collections::BTreeMap;
@ -37,13 +37,24 @@ pub fn list_activities_grouped_by_date(activities: &[&activity::Activity]) {
return;
}
let activities_by_date = group_activities_by_date(activities);
let mut activity_table = table::Table::new(vec![
"Started".to_string(),
"Stopped".to_string(),
"Description".to_string(),
"Project".to_string(),
"Duration".to_string(),
]);
for (date, activity_list) in activities_by_date {
println!("{}", date);
list_activities(&activity_list, false);
println!();
}
group_activities_by_date(activities).iter()
.map(|(date, activity_list)| create_activites_group(&format!("{}", date), activity_list.as_slice()))
.for_each(|g| activity_table.add_group(g));
println!("\n{}", activity_table);
}
fn create_activites_group(title: &str, activities: &[&activity::Activity]) -> table::Group {
let rows = activities.iter().map(|a| get_activity_table_row(&a, false)).collect();
table::Group::new(Some(title.to_string()), rows)
}
// displays a table with running activities (no end time)
@ -118,7 +129,7 @@ fn get_activity_table_row(activity: &&activity::Activity, with_start_dates: bool
]);
if !activity.is_stopped() {
new_row.set_color(Colour::Green);
new_row.set_color(Color::Green.normal());
}
new_row

View file

@ -1,13 +1,12 @@
use std::cmp;
use std::fmt;
use std::fmt::Formatter;
use std::str;
use ansi_term::{Colour, Style};
use nu_ansi_term::Style;
pub struct Row {
content: Vec<String>,
color: Option<Colour>,
style: Option<Style>,
}
pub struct Group {
@ -25,12 +24,12 @@ impl Row {
pub fn new(content: Vec<String>) -> Row {
Row {
content,
color: None,
style: None,
}
}
pub fn set_color(&mut self, color: Colour) {
self.color = Some(color);
pub fn set_color(&mut self, style: Style) {
self.style = Some(style);
}
}
@ -53,23 +52,31 @@ impl Table {
self.rows.push(row);
}
pub fn add_group(&mut self, group: Group) {
self.groups.push(group);
}
fn get_all_rows(&self) -> Vec<&Row> {
self.groups.iter()
.flat_map(|g| g.rows.as_slice())
.chain(self.rows.as_slice())
.collect()
}
fn get_column_width(&self) -> Vec<usize> {
let mut column_width: Vec<usize> = self.header.iter().map(|e| e.chars().count()).collect();
let mut i: usize;
for row in &self.rows {
i = 0;
while let Some(w) = row.content.get(i) {
if let Some(old_w) = column_width.get(i) {
column_width[i] = cmp::max(w.chars().count(), *old_w);
} else {
column_width.push(w.chars().count());
}
i += 1;
}
for row in self.get_all_rows() {
row.content.iter()
.map(|cell| cell.chars().count())
.enumerate()
.for_each(|(i, char_count)| {
if let Some(old_w) = column_width.get(i) {
column_width[i] = cmp::max(char_count, *old_w);
} else {
column_width.push(char_count);
}
});
}
column_width
@ -84,15 +91,37 @@ impl fmt::Display for Table {
writeln!(f)?;
for row in &self.rows {
let style = row.color.map(|color| Style::new().fg(color));
write_cells(f, &row.content, &column_width, style)?;
writeln!(f)?;
write_row(f, row, &column_width)?;
}
for group in &self.groups {
write_group(f, group, &column_width)?;
}
Ok(())
}
}
fn write_group(f: &mut fmt::Formatter<'_>, group: &Group, column_width: &Vec<usize>) -> fmt::Result {
let empty_string = "".to_string();
let title = group.title.as_ref().unwrap_or(&empty_string);
writeln!(f)?;
writeln!(f, "{}", Style::new().bold().paint(title))?;
for row in &group.rows {
write_row(f, row, &column_width)?;
}
Ok(())
}
fn write_row(f: &mut fmt::Formatter<'_>, row: &Row, column_width : &Vec<usize>) -> fmt::Result {
write_cells(f, &row.content, &column_width, row.style)?;
writeln!(f)?;
Ok(())
}
fn write_cells<T: AsRef<str> + std::fmt::Display>(
f: &mut fmt::Formatter<'_>,
cells: &[T],