-
Notifications
You must be signed in to change notification settings - Fork 0
/
json.go
62 lines (54 loc) · 1.56 KB
/
json.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
// Package json defines utilities for converting Starlark values to/from JSON strings based on go.starlark.net/lib/json.
package json
import (
"sync"
itn "github.com/1set/starlet/dataconv"
stdjson "go.starlark.net/lib/json"
"go.starlark.net/starlark"
"go.starlark.net/starlarkstruct"
)
// ModuleName defines the expected name for this Module when used
// in starlark's load() function, eg: load('json', 'encode')
const ModuleName = "json"
var (
once sync.Once
jsonModule starlark.StringDict
)
// LoadModule loads the json module. It is concurrency-safe and idempotent.
func LoadModule() (starlark.StringDict, error) {
once.Do(func() {
mod := starlarkstruct.Module{
Name: ModuleName,
Members: starlark.StringDict{
"dumps": starlark.NewBuiltin("json.dumps", dumps),
},
}
for k, v := range stdjson.Module.Members {
mod.Members[k] = v
}
jsonModule = starlark.StringDict{
ModuleName: &mod,
}
})
return jsonModule, nil
}
func dumps(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
var (
obj starlark.Value
indent = starlark.MakeInt(0)
)
if err := starlark.UnpackArgs(fn.Name(), args, kwargs, "obj", &obj, "indent?", &indent); err != nil {
return starlark.None, err
}
// use 0 as default indent if failed to unpack indent
it, ok := indent.Int64()
if !ok || it < 0 {
it = 0
}
// use internal marshaler to support starlark types
data, err := itn.MarshalStarlarkJSON(obj, int(it))
if err != nil {
return starlark.None, err
}
return starlark.String(data), nil
}