use tabled::Table;
use tabled::builder::Builder as TableBuilder;
use tabled::settings::Style;
use tabled::settings::style::HorizontalLine;
fn build_table(headers: &[&str], rows: &[Vec<String>]) -> Table {
let mut builder = TableBuilder::new();
builder.push_record(headers.iter().copied());
for row in rows {
builder.push_record(row.iter().map(std::string::String::as_str));
}
builder.build()
}
pub fn print_table(headers: &[&str], rows: &[Vec<String>]) {
let mut table = build_table(headers, rows);
crate::output::info(&format!("{}", table.with(Style::rounded())));
}
pub fn print_table_with_total(headers: &[&str], rows: &[Vec<String>], total: &[String]) {
let mut all_rows: Vec<Vec<String>> = rows.to_vec();
all_rows.push(total.to_vec());
let mut table = build_table(headers, &all_rows);
let n_rows = table.count_rows();
let header_line = HorizontalLine::inherit(Style::modern());
let total_line = HorizontalLine::inherit(Style::modern());
let style = Style::rounded().horizontals([(1, header_line), (n_rows - 1, total_line)]);
crate::output::info(&format!("{}", table.with(style)));
}
pub const fn yes_no(b: bool) -> &'static str {
if b { "Yes" } else { "No" }
}
pub const NONE_LABEL: &str = "None";
pub fn opt_json(value: Option<&serde_json::Value>) -> String {
match value {
Some(v) => serde_json::to_string(v).unwrap_or_default(),
None => NONE_LABEL.to_string(),
}
}