table.gno
2.57 Kb · 106 lines
1package table
2
3import (
4 "strings"
5
6 "gno.land/p/nt/ufmt/v0"
7)
8
9// Table defines the structure for a markdown table
10type Table struct {
11 header []string
12 rows [][]string
13}
14
15// Validate checks if the number of columns in each row matches the number of columns in the header
16func (t *Table) Validate() error {
17 numCols := len(t.header)
18 for _, row := range t.rows {
19 if len(row) != numCols {
20 return ufmt.Errorf("row %v does not match header length %d", row, numCols)
21 }
22 }
23 return nil
24}
25
26// New creates a new Table instance, ensuring the header and rows match in size
27func New(header []string, rows [][]string) (*Table, error) {
28 t := &Table{
29 header: header,
30 rows: rows,
31 }
32
33 if err := t.Validate(); err != nil {
34 return nil, err
35 }
36
37 return t, nil
38}
39
40// Table returns a markdown string for the given Table
41func (t *Table) String() string {
42 if err := t.Validate(); err != nil {
43 panic(err)
44 }
45
46 var sb strings.Builder
47
48 sb.WriteString("| " + strings.Join(t.header, " | ") + " |\n")
49 sb.WriteString("| " + strings.Repeat("---|", len(t.header)) + "\n")
50
51 for _, row := range t.rows {
52 sb.WriteString("| " + strings.Join(row, " | ") + " |\n")
53 }
54
55 return sb.String()
56}
57
58// AddRow adds a new row to the table
59func (t *Table) AddRow(row []string) error {
60 if len(row) != len(t.header) {
61 return ufmt.Errorf("row %v does not match header length %d", row, len(t.header))
62 }
63 t.rows = append(t.rows, row)
64 return nil
65}
66
67// AddColumn adds a new column to the table with the specified values
68func (t *Table) AddColumn(header string, values []string) error {
69 if len(values) != len(t.rows) {
70 return ufmt.Errorf("values length %d does not match the number of rows %d", len(values), len(t.rows))
71 }
72
73 // Add the new header
74 t.header = append(t.header, header)
75
76 // Add the new column values to each row
77 for i, value := range values {
78 t.rows[i] = append(t.rows[i], value)
79 }
80 return nil
81}
82
83// RemoveRow removes a row from the table by its index
84func (t *Table) RemoveRow(index int) error {
85 if index < 0 || index >= len(t.rows) {
86 return ufmt.Errorf("index %d is out of range", index)
87 }
88 t.rows = append(t.rows[:index], t.rows[index+1:]...)
89 return nil
90}
91
92// RemoveColumn removes a column from the table by its index
93func (t *Table) RemoveColumn(index int) error {
94 if index < 0 || index >= len(t.header) {
95 return ufmt.Errorf("index %d is out of range", index)
96 }
97
98 // Remove the column from the header
99 t.header = append(t.header[:index], t.header[index+1:]...)
100
101 // Remove the corresponding column from each row
102 for i := range t.rows {
103 t.rows[i] = append(t.rows[i][:index], t.rows[i][index+1:]...)
104 }
105 return nil
106}