// SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2025 The Gleam contributors use ecow::EcoString; /// Generates a string delimeted table with 2 spaces between each column, columns padded with /// enough spaces to be aligned, and hyphens under the headers (excluding the final column of each /// row). Rows should have the right number of columns. /// /// ## Example /// /// ```txt /// Package Current Latest /// ------- ------- ------ /// wibble 1.4.0 1.4.1 /// wobble 1.0.1 2.3.0 /// ``` /// pub fn space_table(headers: &[impl AsRef], data: Grid) -> EcoString where Grid: AsRef<[Row]>, Row: AsRef<[Cell]>, Cell: AsRef, { let mut output = EcoString::new(); let mut column_widths: Vec = headers.iter().map(|header| header.as_ref().len()).collect(); for row in data.as_ref() { for (index, cell) in row.as_ref().iter().enumerate() { if let Some(width) = column_widths.get_mut(index) { let cell = cell.as_ref(); *width = (*width).max(cell.len()); } } } for (index, (header, width)) in headers.iter().zip(column_widths.iter()).enumerate() { if index > 0 { output.push_str(" "); } let header = header.as_ref(); output.push_str(header); if index < headers.len() - 1 { let padding = width - header.len(); if padding > 0 { output.push_str(&" ".repeat(padding)); } } } output.push('\n'); for (index, (header, width)) in headers.iter().zip(column_widths.iter()).enumerate() { if index > 0 { output.push_str(" "); } let header = header.as_ref(); output.push_str(&"-".repeat(header.len())); if index < headers.len() - 1 { let padding = width - header.len(); if padding > 0 { output.push_str(&" ".repeat(padding)); } } } output.push('\n'); for row in data.as_ref() { for (index, (cell, width)) in row.as_ref().iter().zip(column_widths.iter()).enumerate() { if index > 0 { output.push_str(" "); } let cell = cell.as_ref(); output.push_str(cell); if index < headers.len() - 1 { let padding = width - cell.len(); if padding > 0 { output.push_str(&" ".repeat(padding)); } } } output.push('\n'); } output }