Skip to main content

ppt_rs/generator/table/
builder.rs

1//! Table and TableBuilder for constructing tables
2
3use super::row::TableRow;
4
5/// Table definition with rows and positioning
6#[derive(Clone, Debug)]
7pub struct Table {
8    /// Table rows
9    pub rows: Vec<TableRow>,
10    /// Column widths in EMU
11    pub column_widths: Vec<u32>,
12    /// X position in EMU
13    pub x: u32,
14    /// Y position in EMU
15    pub y: u32,
16}
17
18impl Table {
19    /// Create a new table with explicit rows, column widths, and position
20    pub fn new(rows: Vec<TableRow>, column_widths: Vec<u32>, x: u32, y: u32) -> Self {
21        Table { rows, column_widths, x, y }
22    }
23
24    /// Create a table from raw data (2D string array)
25    pub fn from_data(data: Vec<Vec<&str>>, column_widths: Vec<u32>, x: u32, y: u32) -> Self {
26        use super::cell::TableCell;
27        
28        let rows = data
29            .into_iter()
30            .map(|row_data| {
31                TableRow::new(row_data.into_iter().map(TableCell::new).collect())
32            })
33            .collect();
34
35        Table {
36            rows,
37            column_widths,
38            x,
39            y,
40        }
41    }
42
43    /// Calculate total table width
44    pub fn width(&self) -> u32 {
45        self.column_widths.iter().sum()
46    }
47
48    /// Calculate total table height based on row heights
49    pub fn height(&self) -> u32 {
50        self.rows
51            .iter()
52            .map(|row| row.height.unwrap_or(400000))
53            .sum()
54    }
55
56    /// Get the number of rows
57    pub fn row_count(&self) -> usize {
58        self.rows.len()
59    }
60
61    /// Get the number of columns
62    pub fn column_count(&self) -> usize {
63        self.column_widths.len()
64    }
65}
66
67/// Builder for creating tables with fluent API
68#[derive(Clone, Debug)]
69pub struct TableBuilder {
70    column_widths: Vec<u32>,
71    rows: Vec<TableRow>,
72    x: u32,
73    y: u32,
74}
75
76impl TableBuilder {
77    /// Create a new table builder with column widths
78    pub fn new(column_widths: Vec<u32>) -> Self {
79        TableBuilder {
80            column_widths,
81            rows: Vec::new(),
82            x: 0,
83            y: 0,
84        }
85    }
86
87    /// Add a row to the table
88    pub fn add_row(mut self, row: TableRow) -> Self {
89        self.rows.push(row);
90        self
91    }
92
93    /// Set table position
94    pub fn position(mut self, x: u32, y: u32) -> Self {
95        self.x = x;
96        self.y = y;
97        self
98    }
99
100    /// Add a simple row from strings
101    pub fn add_simple_row(mut self, cells: Vec<&str>) -> Self {
102        let row = TableRow::new(
103            cells.into_iter().map(super::cell::TableCell::new).collect(),
104        );
105        self.rows.push(row);
106        self
107    }
108
109    /// Build the final table
110    pub fn build(self) -> Table {
111        Table {
112            rows: self.rows,
113            column_widths: self.column_widths,
114            x: self.x,
115            y: self.y,
116        }
117    }
118}
119
120#[cfg(test)]
121mod tests {
122    use super::*;
123    use crate::generator::table::cell::TableCell;
124
125    #[test]
126    fn test_table_from_data() {
127        let table = Table::from_data(
128            vec![vec!["A", "B"], vec!["1", "2"]],
129            vec![1000000, 1000000],
130            0,
131            0,
132        );
133        assert_eq!(table.row_count(), 2);
134        assert_eq!(table.column_count(), 2);
135    }
136
137    #[test]
138    fn test_table_dimensions() {
139        let table = Table::from_data(
140            vec![vec!["A", "B", "C"]],
141            vec![1000000, 1500000, 2000000],
142            0,
143            0,
144        );
145        assert_eq!(table.width(), 4500000);
146    }
147
148    #[test]
149    fn test_table_builder() {
150        let table = TableBuilder::new(vec![1000000, 1000000])
151            .add_row(TableRow::new(vec![
152                TableCell::new("Header 1"),
153                TableCell::new("Header 2"),
154            ]))
155            .add_row(TableRow::new(vec![
156                TableCell::new("Data 1"),
157                TableCell::new("Data 2"),
158            ]))
159            .position(500000, 1000000)
160            .build();
161
162        assert_eq!(table.row_count(), 2);
163        assert_eq!(table.x, 500000);
164        assert_eq!(table.y, 1000000);
165    }
166}