Skip to main content

fur_cli/renderer/
table.rs

1use colored::*;
2
3pub fn render_table(
4    title: &str,
5    headers: &[&str],
6    rows: Vec<Vec<String>>,
7    active_idx: Option<usize>,
8) {
9    // Compute column widths
10    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    // Total table width
24    let total_width: usize = col_widths.iter().map(|w| w + 4).sum::<usize>() + 2;
25
26    // Top title bar
27    println!("{}", format!("=== {} ===", title).bold().bright_cyan());
28    println!("{}", "-".repeat(total_width));
29
30    // Header
31    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    // Rows
39    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    // Bottom border
54    println!("{}", "-".repeat(total_width));
55}