Calculate column widths based on content and fit them in the available width.
(&self, max_total_width: usize)
| 598 | |
| 599 | /// Calculate column widths based on content and fit them in the available width. |
| 600 | fn calculate_column_widths(&self, max_total_width: usize) -> Vec<usize> { |
| 601 | if self.rows.is_empty() { |
| 602 | return Vec::new(); |
| 603 | } |
| 604 | |
| 605 | let detected_cols = self.rows.iter().map(|r| r.len()).max().unwrap_or(0); |
| 606 | let num_cols = self.alignments.len().max(detected_cols); |
| 607 | if num_cols == 0 { |
| 608 | return Vec::new(); |
| 609 | } |
| 610 | |
| 611 | // Keep each column visible even in very narrow terminals. |
| 612 | let mut widths = vec![1usize; num_cols]; |
| 613 | for row in &self.rows { |
| 614 | for (i, cell) in row.iter().enumerate().take(num_cols) { |
| 615 | let cell_width: usize = cell |
| 616 | .iter() |
| 617 | .map(|s| UnicodeWidthStr::width(s.content.as_ref())) |
| 618 | .sum(); |
| 619 | widths[i] = widths[i].max(cell_width.max(1)); |
| 620 | } |
| 621 | } |
| 622 | |
| 623 | // Total width for "│ {cell} │" repeated across columns: |
| 624 | // sum(column_widths) + (3 * num_cols + 1) |
| 625 | let border_and_padding = 3usize.saturating_mul(num_cols).saturating_add(1); |
| 626 | let target_content_width = max_total_width |
| 627 | .saturating_sub(border_and_padding) |
| 628 | .max(num_cols); |
| 629 | let mut current_content_width: usize = widths.iter().sum(); |
| 630 | |
| 631 | while current_content_width > target_content_width { |
| 632 | let widest = widths |
| 633 | .iter() |
| 634 | .enumerate() |
| 635 | .filter(|(_, w)| **w > 1) |
| 636 | .max_by_key(|(_, w)| **w) |
| 637 | .map(|(idx, _)| idx); |
| 638 | let Some(idx) = widest else { |
| 639 | break; |
| 640 | }; |
| 641 | widths[idx] -= 1; |
| 642 | current_content_width -= 1; |
| 643 | } |
| 644 | |
| 645 | widths |
| 646 | } |
| 647 | |
| 648 | /// Render the table to lines with wrapped cells. |
| 649 | fn render_table(&self, max_total_width: usize) -> Vec<Line<'static>> { |
no test coverage detected