output.go 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. // Package output renders command results as a table or as JSON.
  2. package output
  3. import (
  4. "encoding/json"
  5. "fmt"
  6. "io"
  7. "strings"
  8. "text/tabwriter"
  9. )
  10. // Format is a rendering mode for command output.
  11. type Format string
  12. // Supported formats.
  13. const (
  14. Table Format = "table"
  15. JSON Format = "json"
  16. )
  17. // Parse validates a user-supplied format name.
  18. func Parse(s string) (Format, error) {
  19. switch Format(strings.ToLower(strings.TrimSpace(s))) {
  20. case Table, "":
  21. return Table, nil
  22. case JSON:
  23. return JSON, nil
  24. default:
  25. return "", fmt.Errorf("unknown output format %q: use table or json", s)
  26. }
  27. }
  28. // Write renders v according to format. Table rendering uses header and rows so
  29. // every command lays out the same way.
  30. func Write(w io.Writer, format Format, header []string, rows [][]string, v any) error {
  31. if format == JSON {
  32. enc := json.NewEncoder(w)
  33. enc.SetIndent("", " ")
  34. return enc.Encode(v)
  35. }
  36. if len(header) == 0 && len(rows) == 0 {
  37. return nil
  38. }
  39. tw := tabwriter.NewWriter(w, 0, 0, 2, ' ', 0)
  40. if len(header) > 0 {
  41. fmt.Fprintln(tw, strings.Join(header, "\t"))
  42. }
  43. for _, row := range rows {
  44. fmt.Fprintln(tw, strings.Join(row, "\t"))
  45. }
  46. return tw.Flush()
  47. }