package table import ( "fmt" "io" "reflect" ) type JSONPrinter struct { headers []string writer io.Writer continued bool } // Headers specify the table headers func (p *JSONPrinter) Headers(headers ...string) error { p.headers = make([]string, len(headers), len(headers)) for idx := range headers { p.headers[idx] = headers[idx] } _, err := fmt.Fprintf(p.writer, "[\n") return err } func (p *JSONPrinter) preamble() error { if p.continued { if _, err := fmt.Fprintf(p.writer, ",\n"); err != nil { return err } } if _, err := fmt.Fprintf(p.writer, "{\n"); err != nil { return err } return nil } // Fields add another row func (p *JSONPrinter) Fields(fields ...interface{}) error { if err := p.preamble(); err != nil { return err } eol := ",\n" for idx := range fields { var err error if idx == len(fields)-1 { eol = "\n" } field := fields[idx] switch field.(type) { case string: _, err = fmt.Fprintf(p.writer, "\"%s\":\"%v\"%s", p.headers[idx], field, eol) case int, uint, int8, uint8, int32, uint32, int64, uint64, float32, float64: _, err = fmt.Fprintf(p.writer, "\"%s\": %v%s", p.headers[idx], field, eol) default: err = fmt.Errorf("unsupported field type : %s", reflect.TypeOf(field).Name()) } if err != nil { return err } } p.continued = true _, err := fmt.Fprintf(p.writer, "}\n") return err } func (p *JSONPrinter) StringFields(fields ...string) error { if err := p.preamble(); err != nil { return err } eol := ",\n" for idx, field := range fields { if idx == len(fields)-1 { eol = "\n" } _, err := fmt.Fprintf(p.writer, "\"%s\":\"%v\"%s", p.headers[idx], field, eol) if err != nil { return err } } p.continued = true _, err := fmt.Fprintf(p.writer, "}\n") return err } // Flush implements the flush interface but for CVS printer is a noop func (p *JSONPrinter) Flush() error { _, err := fmt.Fprintf(p.writer, "]\n") return err }