package formatters import ( "bytes" "encoding/json" "fmt" "time" "codeberg.org/danjones000/my-log/models" "github.com/spf13/viper" ) const FormatJSON string = "json" func newJson(ff *viper.Viper) (Formatter, error) { js := new(Json) err := ff.Unmarshal(js) if err != nil { return nil, fmt.Errorf("failed to get json config: %w", err) } return js, nil } type Json struct { prettPrint bool `mapstructure:"pretty_print"` } func (js *Json) Name() string { return FormatJSON } func (js *Json) marshal(v any) (o []byte, err error) { o, err = json.Marshal(v) if err != nil { return } if js.prettPrint { buff := &bytes.Buffer{} err = json.Indent(buff, o, "", "\t") if err == nil { o = buff.Bytes() } } return } func (js *Json) Meta(m models.Meta) ([]byte, error) { o := map[string]any{m.Key: m.Value} return js.marshal(o) } func (js *Json) entryMap(e models.Entry) map[string]any { o := map[string]any{ "title": e.Title, "date": e.Date.Format(time.RFC3339), } for _, m := range e.Fields { o[m.Key] = m.Value } return o } func (js *Json) Entry(e models.Entry) ([]byte, error) { return js.marshal(js.entryMap(e)) } func (js *Json) Log(l models.Log) ([]byte, error) { return js.Logs([]models.Log{l}) } func (js *Json) Logs(logs []models.Log) (out []byte, err error) { if len(logs) == 0 { return } o := map[string][]map[string]any{} for _, l := range logs { es := []map[string]any{} for _, e := range l.Entries { es = append(es, js.entryMap(e)) } o[l.Name] = es } return js.marshal(o) }