1package table23import (4 "strings"56 "gno.land/p/nt/ufmt/v0"7)89// Table defines the structure for a markdown table10type Table struct {11 header []string12 rows [][]string13}1415// Validate checks if the number of columns in each row matches the number of columns in the header16func (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 nil24}2526// New creates a new Table instance, ensuring the header and rows match in size27func New(header []string, rows [][]string) (*Table, error) {28 t := &Table{29 header: header,30 rows: rows,31 }3233 if err := t.Validate(); err != nil {34 return nil, err35 }3637 return t, nil38}3940// Table returns a markdown string for the given Table41func (t *Table) String() string {42 if err := t.Validate(); err != nil {43 panic(err)44 }4546 var sb strings.Builder4748 sb.WriteString("| " + strings.Join(t.header, " | ") + " |\n")49 sb.WriteString("| " + strings.Repeat("---|", len(t.header)) + "\n")5051 for _, row := range t.rows {52 sb.WriteString("| " + strings.Join(row, " | ") + " |\n")53 }5455 return sb.String()56}5758// AddRow adds a new row to the table59func (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 nil65}6667// AddColumn adds a new column to the table with the specified values68func (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 }7273 // Add the new header74 t.header = append(t.header, header)7576 // Add the new column values to each row77 for i, value := range values {78 t.rows[i] = append(t.rows[i], value)79 }80 return nil81}8283// RemoveRow removes a row from the table by its index84func (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 nil90}9192// RemoveColumn removes a column from the table by its index93func (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 }9798 // Remove the column from the header99 t.header = append(t.header[:index], t.header[index+1:]...)100101 // Remove the corresponding column from each row102 for i := range t.rows {103 t.rows[i] = append(t.rows[i][:index], t.rows[i][index+1:]...)104 }105 return nil106}107Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.