summaryrefslogtreecommitdiffstats
path: root/src/row.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/row.rs')
-rw-r--r--src/row.rs71
1 files changed, 56 insertions, 15 deletions
diff --git a/src/row.rs b/src/row.rs
index f02f9ef..a604dc7 100644
--- a/src/row.rs
+++ b/src/row.rs
@@ -28,9 +28,17 @@ impl Row {
Self::new(vec![Cell::default(); 0])
}
+ /// Count the number of column required in the table grid.
+ /// It takes into account horizontal spanning of cells. For
+ /// example, a cell with an hspan of 3 will add 3 column to the grid
+ pub fn column_count(&self) -> usize {
+ self.cells.iter().map(|c| c.get_hspan()).sum()
+ }
+
/// Get the number of cells in this row
pub fn len(&self) -> usize {
self.cells.len()
+ // self.cells.iter().map(|c| c.get_hspan()).sum()
}
/// Check if the row is empty (has no cell)
@@ -52,11 +60,31 @@ impl Row {
/// Get the minimum width required by the cell in the column `column`.
/// Return 0 if the cell does not exist in this row
- pub fn get_cell_width(&self, column: usize) -> usize {
- self.cells
- .get(column)
- .map(|cell| cell.get_width())
- .unwrap_or(0)
+ pub fn get_column_width(&self, column: usize, format: &TableFormat) -> usize {
+ let mut i = 0;
+ for c in &self.cells {
+ if i + c.get_hspan()-1 >= column {
+ if c.get_hspan() == 1 {
+ return c.get_width();
+ }
+ let (lp, rp) = format.get_padding();
+ let sep = format.get_column_separator(ColumnPosition::Intern).map(|_| 1).unwrap_or_default();
+ let rem = lp + rp +sep;
+ let mut w = c.get_width();
+ if w > rem {
+ w -= rem;
+ } else {
+ w = 0;
+ }
+ return (w as f64 / c.get_hspan() as f64).ceil() as usize;
+ }
+ i += c.get_hspan();
+ }
+ 0
+ // self.cells
+ // .get(column)
+ // .map(|cell| cell.get_width())
+ // .unwrap_or(0)
}
/// Get the cell at index `idx`
@@ -69,12 +97,12 @@ impl Row {
self.cells.get_mut(idx)
}
- /// Set the `cell` in the row at the given `column`
- pub fn set_cell(&mut self, cell: Cell, column: usize) -> Result<(), &str> {
- if column >= self.len() {
+ /// Set the `cell` in the row at the given `idx` index
+ pub fn set_cell(&mut self, cell: Cell, idx: usize) -> Result<(), &str> {
+ if idx >= self.len() {
return Err("Cannot find cell");
}
- self.cells[column] = cell;
+ self.cells[idx] = cell;
Ok(())
}
@@ -124,18 +152,31 @@ impl Row {
out.write_all(&vec![b' '; format.get_indent()])?;
format.print_column_separator(out, ColumnPosition::Left)?;
let (lp, rp) = format.get_padding();
- for j in 0..col_width.len() {
- out.write_all(&vec![b' '; lp])?;
+ let mut j = 0;
+ let mut hspan = 0; // The additional offset caused by cell's horizontal spanning
+ while j+hspan < col_width.len() {
+ out.write_all(&vec![b' '; lp])?; // Left padding
+ // skip_r_fill skip filling the end of the last cell if there's no character
+ // delimiting the end of the table
let skip_r_fill = (j == col_width.len() - 1) &&
format.get_column_separator(ColumnPosition::Right).is_none();
match self.get_cell(j) {
- Some(c) => f(c, out, i, col_width[j], skip_r_fill)?,
- None => f(&Cell::default(), out, i, col_width[j], skip_r_fill)?,
+ Some(c) => {
+ // In case of horizontal spanning, width is the sum of all spanned columns' width
+ let mut w = col_width[j+hspan..j+hspan+c.get_hspan()].iter().sum();
+ let real_span = c.get_hspan()-1;
+ w += real_span * (lp + rp) + real_span * format.get_column_separator(ColumnPosition::Intern).map(|_| 1).unwrap_or_default();
+ // Print cell content
+ f(c, out, i, w, skip_r_fill)?;
+ hspan += real_span; // Add span to offset
+ },
+ None => f(&Cell::default(), out, i, col_width[j+hspan], skip_r_fill)?,
};
- out.write_all(&vec![b' '; rp])?;
- if j < col_width.len() - 1 {
+ out.write_all(&vec![b' '; rp])?; // Right padding
+ if j+hspan < col_width.len() - 1 {
format.print_column_separator(out, ColumnPosition::Intern)?;
}
+ j+=1;
}
format.print_column_separator(out, ColumnPosition::Right)?;
out.write_all(NEWLINE)?;