You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

67 lines
1.2 KiB
Go

package main
import (
"encoding/json"
"fmt"
"slices"
"strings"
)
type Document struct {
Header []string
Rows [][]string
}
func (d Document) MarshalJSON() ([]byte, error) {
headers := keys(d.Header)
var ret strings.Builder
ret.WriteRune('[')
for i, row := range d.Rows {
ret.WriteRune('{')
for j, col := range row {
obj, err := json.Marshal(map[string]string{headers[j]: col})
if err != nil {
return nil, fmt.Errorf("failed to marshal %s: %w", headers[j], err)
}
ret.WriteString(strings.Trim(string(obj), "{}"))
if j < len(row)-1 {
ret.WriteRune(',')
}
}
if i < len(d.Rows)-1 {
ret.WriteString("},")
} else {
ret.WriteRune('}')
}
}
ret.WriteRune(']')
return []byte(ret.String()), nil
}
func (d *Document) setHeader(h []string) error {
d.Header = h
return nil
}
func (d *Document) addRow(row []string) error {
d.Rows = append(d.Rows, row)
return nil
}
func keys(list []string) []string {
keys := make([]string, 0, len(list))
for _, h := range list {
heading := h
index := 0
for slices.Contains(keys, heading) {
index++
heading = fmt.Sprintf("%s_%d", h, index)
}
keys = append(keys, heading)
}
return keys
}