Render the table to a string.
(&self)
| 453 | |
| 454 | /// Render the table to a string. |
| 455 | fn render(&self) -> String { |
| 456 | if self.columns.is_empty() { |
| 457 | return String::new(); |
| 458 | } |
| 459 | |
| 460 | let widths = self.calculate_widths(); |
| 461 | let mut output = String::new(); |
| 462 | |
| 463 | // Render header |
| 464 | let header_cells: Vec<String> = self |
| 465 | .columns |
| 466 | .iter() |
| 467 | .enumerate() |
| 468 | .map(|(i, col)| { |
| 469 | let text = Self::truncate(&col.header, col.max_width); |
| 470 | col.alignment.apply(&text, widths[i]) |
| 471 | }) |
| 472 | .collect(); |
| 473 | output.push_str(&header_cells.join(&self.column_separator)); |
| 474 | output.push('\n'); |
| 475 | |
| 476 | // Render header separator |
| 477 | if self.show_header_separator { |
| 478 | let separator_cells: Vec<String> = widths.iter().map(|w| "─".repeat(*w)).collect(); |
| 479 | output.push_str(&separator_cells.join(&self.column_separator)); |
| 480 | output.push('\n'); |
| 481 | } |
| 482 | |
| 483 | // Render rows |
| 484 | for row in &self.rows { |
| 485 | let row_cells: Vec<String> = self |
| 486 | .columns |
| 487 | .iter() |
| 488 | .enumerate() |
| 489 | .map(|(i, col)| { |
| 490 | let cell_text = row.cells.get(i).map(|s| s.as_str()).unwrap_or(""); |
| 491 | let text = Self::truncate(cell_text, col.max_width); |
| 492 | col.alignment.apply(&text, widths[i]) |
| 493 | }) |
| 494 | .collect(); |
| 495 | output.push_str(&row_cells.join(&self.column_separator)); |
| 496 | output.push('\n'); |
| 497 | } |
| 498 | |
| 499 | // Remove trailing newline |
| 500 | if output.ends_with('\n') { |
| 501 | output.pop(); |
| 502 | } |
| 503 | |
| 504 | output |
| 505 | } |
| 506 | } |
| 507 | |
| 508 | impl fmt::Display for Table { |