fur_cli/renderer/
table.rs1use colored::*;
2
3pub fn render_table(
7 title: &str,
8 headers: &[&str],
9 rows: Vec<Vec<String>>,
10 active_idx: Option<usize>,
11 spaced: bool,
12) {
13 let width_of = |s: &str| s.chars().count();
18
19 let col_widths: Vec<usize> = headers
20 .iter()
21 .enumerate()
22 .map(|(i, h)| {
23 let max_cell = rows
24 .iter()
25 .map(|r| r.get(i).map(|s| width_of(s)).unwrap_or(0))
26 .max()
27 .unwrap_or(0);
28 max_cell.max(width_of(h))
29 })
30 .collect();
31
32 let total_width: usize = col_widths.iter().map(|w| w + 4).sum::<usize>() + 2;
34
35 println!("{}", format!("=== {} ===", title).bold().bright_cyan());
37 println!("{}", "-".repeat(total_width));
38
39 let mut header_line = String::new();
41 for (i, h) in headers.iter().enumerate() {
42 header_line.push_str(&format!("{:width$} ", h, width = col_widths[i]));
43 }
44 println!("{}", header_line.bold());
45 println!("{}", "=".repeat(total_width));
46
47 for (i, row) in rows.iter().enumerate() {
48 let mut line = String::new();
49 for (j, cell) in row.iter().enumerate() {
50 line.push_str(&format!("{:width$} ", cell, width = col_widths[j]));
51 }
52
53 if Some(i) == active_idx {
54 println!("{}", line.bold().bright_yellow());
55 } else {
56 println!("{}", line);
57 }
58
59 if spaced {
60 println!();
61 }
62 }
63
64 println!("{}", "-".repeat(total_width));
66}