use comfy_table::*;
#[derive(Debug)]
pub struct TableWrapper {
table: Table,
pub(crate) max_width: Option<u16>,
nested_tables: Vec<TableWrapper>,
}
impl Default for TableWrapper {
fn default() -> Self {
Self {
table: Table::new(),
max_width: None,
nested_tables: vec![],
}
}
}
impl std::ops::Deref for TableWrapper {
type Target = Table;
fn deref(&self) -> &Self::Target {
&self.table
}
}
impl std::ops::DerefMut for TableWrapper {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.table
}
}
impl TableWrapper {
pub fn show(self) -> String {
self.show_recursive(0)
}
pub fn add_table(mut self, table: impl IntoIterator<Item = TableWrapper>) -> Self {
self.nested_tables.extend(table);
self
}
fn show_recursive(self, level: u16) -> String {
let Self {
mut table,
max_width,
nested_tables,
} = self;
let width_decider = match level {
0 => Ord::max,
1 => Ord::min,
_ => {
unimplemented!("Nesting tables more than one level isn't supported yet");
}
};
let tables = nested_tables
.into_iter()
.map(|table| table.show_recursive(level + 1))
.map(|x| vec![x]);
table.add_rows(tables);
let content_width = table.column_max_content_widths().iter().sum::<u16>();
let widths = max_width
.map(|width| width_decider(width, content_width))
.map(|width| width - 2 * (1 + 4 * level))
.map(|width| width / table.column_count() as u16)
.into_iter()
.map(Width::Fixed)
.map(ColumnConstraint::Absolute)
.cycle()
.chain(
max_width
.is_none()
.then_some(ColumnConstraint::ContentWidth)
.into_iter()
.cycle(),
);
table.set_constraints(widths);
format!("{table}")
}
}