1
1
mirror of https://github.com/wader/fq.git synced 2024-11-24 11:16:09 +03:00
fq/format/toml/toml.go
2022-07-27 13:22:59 +02:00

70 lines
1.5 KiB
Go

package toml
import (
"bytes"
"embed"
"github.com/BurntSushi/toml"
"github.com/wader/fq/format"
"github.com/wader/fq/internal/gojqextra"
"github.com/wader/fq/pkg/bitio"
"github.com/wader/fq/pkg/decode"
"github.com/wader/fq/pkg/interp"
"github.com/wader/fq/pkg/scalar"
)
//go:embed toml.jq
var tomlFS embed.FS
func init() {
interp.RegisterFormat(decode.Format{
Name: format.TOML,
Description: "Tom's Obvious, Minimal Language",
ProbeOrder: format.ProbeOrderText,
Groups: []string{format.PROBE},
DecodeFn: decodeTOML,
Functions: []string{"_todisplay"},
})
interp.RegisterFS(tomlFS)
interp.RegisterFunc0("totoml", toTOML)
}
func decodeTOML(d *decode.D, _ any) any {
br := d.RawLen(d.Len())
var r any
if _, err := toml.NewDecoder(bitio.NewIOReader(br)).Decode(&r); err != nil {
d.Fatalf("%s", err)
}
var s scalar.S
s.Actual = gojqextra.Normalize(r)
// TODO: better way to handle that an empty file is valid toml and parsed as an object
switch v := s.Actual.(type) {
case map[string]any:
if len(v) == 0 {
d.Fatalf("root object has no values")
}
case []any:
default:
d.Fatalf("root not object or array")
}
d.Value.V = &s
d.Value.Range.Len = d.Len()
return nil
}
func toTOML(_ *interp.Interp, c any) any {
if c == nil {
return gojqextra.FuncTypeError{Name: "totoml", V: c}
}
b := &bytes.Buffer{}
if err := toml.NewEncoder(b).Encode(gojqextra.Normalize(c)); err != nil {
return err
}
return b.String()
}