-
Notifications
You must be signed in to change notification settings - Fork 227
/
toml.go
69 lines (58 loc) · 1.44 KB
/
toml.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package toml
import (
"bytes"
"embed"
"github.com/BurntSushi/toml"
"github.com/wader/fq/format"
"github.com/wader/fq/internal/gojqex"
"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.ProbeOrderTextFuzzy,
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 = gojqex.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 gojqex.FuncTypeError{Name: "totoml", V: c}
}
b := &bytes.Buffer{}
if err := toml.NewEncoder(b).Encode(gojqex.Normalize(c)); err != nil {
return err
}
return b.String()
}