fur_cli/renderer/
table.rs1use colored::*;
2
3pub fn render_table(
4 title: &str,
5 headers: &[&str],
6 rows: Vec<Vec<String>>,
7 active_idx: Option<usize>,
8) {
9 let col_widths: Vec<usize> = headers
11 .iter()
12 .enumerate()
13 .map(|(i, h)| {
14 let max_cell = rows
15 .iter()
16 .map(|r| r.get(i).map(|s| s.len()).unwrap_or(0))
17 .max()
18 .unwrap_or(0);
19 max_cell.max(h.len())
20 })
21 .collect();
22
23 let total_width: usize = col_widths.iter().map(|w| w + 4).sum::<usize>() + 2;
25
26 println!("{}", format!("=== {} ===", title).bold().bright_cyan());
28 println!("{}", "-".repeat(total_width));
29
30 let mut header_line = String::new();
32 for (i, h) in headers.iter().enumerate() {
33 header_line.push_str(&format!("{:width$} ", h, width = col_widths[i]));
34 }
35 println!("{}", header_line.bold());
36 println!("{}", "=".repeat(total_width));
37
38 for (i, row) in rows.iter().enumerate() {
40 let mut line = String::new();
41 for (j, cell) in row.iter().enumerate() {
42 line.push_str(&format!("{:width$} ", cell, width = col_widths[j]));
43 }
44
45 if Some(i) == active_idx {
46 println!("{}", line.bold().bright_yellow());
47 } else {
48 println!("{}", line);
49 }
50 println!();
51 }
52
53 println!("{}", "-".repeat(total_width));
55}