Fork of daniellemaywood.uk/gleam — Wasm codegen work
2.6 kB
87 lines
1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: 2025 The Gleam contributors
3
4use ecow::EcoString;
5
6/// Generates a string delimeted table with 2 spaces between each column, columns padded with
7/// enough spaces to be aligned, and hyphens under the headers (excluding the final column of each
8/// row). Rows should have the right number of columns.
9///
10/// ## Example
11///
12/// ```txt
13/// Package Current Latest
14/// ------- ------- ------
15/// wibble 1.4.0 1.4.1
16/// wobble 1.0.1 2.3.0
17/// ```
18///
19pub fn space_table<Grid, Row, Cell>(headers: &[impl AsRef<str>], data: Grid) -> EcoString
20where
21 Grid: AsRef<[Row]>,
22 Row: AsRef<[Cell]>,
23 Cell: AsRef<str>,
24{
25 let mut output = EcoString::new();
26
27 let mut column_widths: Vec<usize> =
28 headers.iter().map(|header| header.as_ref().len()).collect();
29
30 for row in data.as_ref() {
31 for (index, cell) in row.as_ref().iter().enumerate() {
32 if let Some(width) = column_widths.get_mut(index) {
33 let cell = cell.as_ref();
34 *width = (*width).max(cell.len());
35 }
36 }
37 }
38
39 for (index, (header, width)) in headers.iter().zip(column_widths.iter()).enumerate() {
40 if index > 0 {
41 output.push_str(" ");
42 }
43 let header = header.as_ref();
44 output.push_str(header);
45 if index < headers.len() - 1 {
46 let padding = width - header.len();
47 if padding > 0 {
48 output.push_str(&" ".repeat(padding));
49 }
50 }
51 }
52 output.push('\n');
53
54 for (index, (header, width)) in headers.iter().zip(column_widths.iter()).enumerate() {
55 if index > 0 {
56 output.push_str(" ");
57 }
58 let header = header.as_ref();
59 output.push_str(&"-".repeat(header.len()));
60 if index < headers.len() - 1 {
61 let padding = width - header.len();
62 if padding > 0 {
63 output.push_str(&" ".repeat(padding));
64 }
65 }
66 }
67 output.push('\n');
68
69 for row in data.as_ref() {
70 for (index, (cell, width)) in row.as_ref().iter().zip(column_widths.iter()).enumerate() {
71 if index > 0 {
72 output.push_str(" ");
73 }
74 let cell = cell.as_ref();
75 output.push_str(cell);
76 if index < headers.len() - 1 {
77 let padding = width - cell.len();
78 if padding > 0 {
79 output.push_str(&" ".repeat(padding));
80 }
81 }
82 }
83 output.push('\n');
84 }
85
86 output
87}