modern_terminal/components/
table.rs

1pub enum Size {
2    Cells(usize),
3}
4
5pub struct Table {
6    pub column_sizes: Vec<Size>,
7    pub rows:         Vec<Vec<Box<dyn crate::core::render::Render>>>,
8}
9
10impl crate::core::render::Render for Table {
11    fn render(
12        &self,
13        options: &crate::core::render::Options,
14    ) -> crate::core::segment::RenderedSegments {
15        let mut rendered_segments = Vec::new();
16
17        let column_sizes: Vec<usize> = self
18            .column_sizes
19            .iter()
20            .map(|column_size| match column_size {
21                Size::Cells(cells) => *cells,
22            })
23            .collect();
24
25        for row in self.rows.iter() {
26            let mut columns_rendered_segments: Vec<
27                crate::core::segment::RenderedSegments,
28            > = Vec::with_capacity(row.len());
29
30            for (column_index, component) in row.iter().enumerate() {
31                columns_rendered_segments.push(component.render(
32                    &crate::core::render::Options {
33                        columns: Some(column_sizes[column_index]),
34                        ..*options
35                    },
36                ));
37            }
38
39            let mut index: usize = 0;
40            let mut done: usize = 0;
41
42            while done < columns_rendered_segments.len() {
43                rendered_segments.push(String::new());
44
45                for (columns_index, column_rendered_segments) in
46                    columns_rendered_segments.iter().enumerate()
47                {
48                    if index < column_rendered_segments.len() {
49                        rendered_segments
50                            .last_mut()
51                            .unwrap()
52                            .push_str(&column_rendered_segments[index]);
53                    }
54                    else {
55                        rendered_segments.last_mut().unwrap().push_str(
56                            &std::iter::repeat(" ")
57                                .take(column_sizes[columns_index])
58                                .collect::<String>(),
59                        );
60                    }
61
62                    if column_rendered_segments.len() == index + 1 {
63                        done += 1;
64                    }
65                }
66                index += 1;
67            }
68        }
69
70        rendered_segments
71    }
72}