| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970 |
- package render
- import (
- "encoding/json"
- "fmt"
- "io"
- "github.com/kotoyuuko/zenmux-usage-cli/internal/api"
- )
- // jsonAccountEntry is the shape of each element in multi-account JSON mode.
- type jsonAccountEntry struct {
- Account string `json:"account"`
- Success bool `json:"success"`
- Data *api.Data `json:"data"`
- Error *string `json:"error"`
- }
- // RenderJSONSingle writes the raw API body to w with a trailing newline.
- // Used when exactly one account was resolved — preserves the exact shape
- // returned by the API so `jq .data.plan.tier` keeps working.
- func RenderJSONSingle(w io.Writer, raw []byte) error {
- if _, err := w.Write(raw); err != nil {
- return err
- }
- if len(raw) == 0 || raw[len(raw)-1] != '\n' {
- if _, err := w.Write([]byte{'\n'}); err != nil {
- return err
- }
- }
- return nil
- }
- // RenderJSONMulti emits an ordered JSON array with one object per result.
- // Successful entries have data populated and error: null; failed entries
- // have data: null and a non-empty error message.
- func RenderJSONMulti(w io.Writer, results []AccountResult) error {
- out := make([]jsonAccountEntry, len(results))
- for i, r := range results {
- entry := jsonAccountEntry{Account: r.Name}
- switch {
- case r.Err != nil:
- entry.Success = false
- msg := r.Err.Error()
- entry.Error = &msg
- case r.Response == nil:
- entry.Success = false
- msg := "no response"
- entry.Error = &msg
- default:
- entry.Success = r.Response.Success
- entry.Data = &r.Response.Data
- if !r.Response.Success {
- msg := r.Response.Error
- if msg == "" {
- msg = "api returned success=false"
- }
- entry.Error = &msg
- entry.Data = nil
- }
- }
- out[i] = entry
- }
- enc := json.NewEncoder(w)
- enc.SetIndent("", " ")
- if err := enc.Encode(out); err != nil {
- return fmt.Errorf("encode multi-account json: %w", err)
- }
- return nil
- }
|