rustic_rs/commands/tui/widgets/
sized_table.rs

1use super::{Constraint, Draw, Frame, Rect, Row, SizedWidget, Table, Text};
2
3pub struct SizedTable {
4    table: Table<'static>,
5    height: usize,
6    width: usize,
7}
8
9impl SizedTable {
10    pub fn new(content: Vec<Vec<Text<'static>>>) -> Self {
11        let height = content
12            .iter()
13            .map(|row| row.iter().map(Text::height).max().unwrap_or_default())
14            .sum::<usize>();
15
16        let widths = content
17            .iter()
18            .map(|row| row.iter().map(Text::width).collect())
19            .reduce(|widths: Vec<usize>, row| {
20                row.iter()
21                    .zip(widths.iter())
22                    .map(|(r, w)| r.max(w))
23                    .copied()
24                    .collect()
25            })
26            .unwrap_or_default();
27
28        let width = widths
29            .iter()
30            .copied()
31            .reduce(|width, w| width + w + 1) // +1 because of space between entries
32            .unwrap_or_default();
33
34        let rows = content.into_iter().map(Row::new);
35        let table = Table::default()
36            .widths(widths.iter().map(|w| {
37                (*w).try_into()
38                    .ok()
39                    .map_or(Constraint::Min(0), Constraint::Length)
40            }))
41            .rows(rows);
42        Self {
43            table,
44            height,
45            width,
46        }
47    }
48}
49
50impl SizedWidget for SizedTable {
51    fn height(&self) -> Option<u16> {
52        self.height.try_into().ok()
53    }
54    fn width(&self) -> Option<u16> {
55        self.width.try_into().ok()
56    }
57}
58
59impl Draw for SizedTable {
60    fn draw(&mut self, area: Rect, f: &mut Frame<'_>) {
61        f.render_widget(&self.table, area);
62    }
63}