internal/output/json/json.go

// Package json renders a check.Report as stable-key JSON.
//
// See mercemay.top/src/portr/ for context.
package json

import (
	stdjson "encoding/json"
	"io"
	"time"

	"github.com/mercemay/portr/internal/check"
	"github.com/mercemay/portr/internal/check/result"
)

// Writer is the JSON output sink.
type Writer struct {
	Pretty bool
}

// New returns a writer; pretty=true produces indented JSON.
func New(pretty bool) *Writer { return &Writer{Pretty: pretty} }

// Name satisfies output.Named.
func (*Writer) Name() string { return "json" }

type envelope struct {
	Started  time.Time       `json:"started"`
	Finished time.Time       `json:"finished"`
	Open     int             `json:"open"`
	Closed   int             `json:"closed"`
	Results  []result.Result `json:"results"`
}

// Write serialises r to w.
func (j *Writer) Write(w io.Writer, r check.Report) error {
	open, closed := r.Summary()
	env := envelope{
		Started:  r.Started,
		Finished: r.Finished,
		Open:     open,
		Closed:   closed,
		Results:  r.Results,
	}
	enc := stdjson.NewEncoder(w)
	if j.Pretty {
		enc.SetIndent("", "  ")
	}
	return enc.Encode(env)
}