All checks were successful
CI/CD / detect-changes (push) Successful in 4s
CI/CD / test-frontend (push) Has been skipped
CI/CD / test-runners (push) Has been skipped
CI/CD / e2e-smoke (push) Has been skipped
CI/CD / test-go-pg (push) Successful in 2m51s
CI/CD / test-sqlite (push) Successful in 3m1s
CI/CD / build-and-deploy (push) Successful in 1m17s
Co-authored-by: Jeffrey Smith <jasafpro@gmail.com> Co-committed-by: Jeffrey Smith <jasafpro@gmail.com>
102 lines
2.3 KiB
Go
102 lines
2.3 KiB
Go
package sandbox
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"go.starlark.net/starlark"
|
|
)
|
|
|
|
// GoToStarlark converts a Go value (typically from JSON unmarshal) to a
|
|
// starlark.Value. Handles nil, bool, int, int64, float64, string,
|
|
// map[string]any, []any, and their interface{} equivalents. Unknown
|
|
// types are stringified.
|
|
func GoToStarlark(v any) starlark.Value {
|
|
switch val := v.(type) {
|
|
case nil:
|
|
return starlark.None
|
|
case bool:
|
|
return starlark.Bool(val)
|
|
case int:
|
|
return starlark.MakeInt(val)
|
|
case int64:
|
|
return starlark.MakeInt64(val)
|
|
case float64:
|
|
if val == float64(int64(val)) {
|
|
return starlark.MakeInt64(int64(val))
|
|
}
|
|
return starlark.Float(val)
|
|
case string:
|
|
return starlark.String(val)
|
|
case map[string]any:
|
|
return MapToDict(val)
|
|
case []any:
|
|
elems := make([]starlark.Value, len(val))
|
|
for i, e := range val {
|
|
elems[i] = GoToStarlark(e)
|
|
}
|
|
return starlark.NewList(elems)
|
|
default:
|
|
return starlark.String(fmt.Sprintf("%v", val))
|
|
}
|
|
}
|
|
|
|
// StarlarkToGo converts a starlark.Value to a Go value suitable for
|
|
// JSON serialization. Handles None, Bool, Int, Float, String, List,
|
|
// Dict, and Tuple.
|
|
func StarlarkToGo(v starlark.Value) any {
|
|
switch val := v.(type) {
|
|
case starlark.NoneType:
|
|
return nil
|
|
case starlark.Bool:
|
|
return bool(val)
|
|
case starlark.Int:
|
|
if i, ok := val.Int64(); ok {
|
|
return i
|
|
}
|
|
return val.String()
|
|
case starlark.Float:
|
|
return float64(val)
|
|
case starlark.String:
|
|
return string(val)
|
|
case *starlark.List:
|
|
result := make([]any, val.Len())
|
|
for i := 0; i < val.Len(); i++ {
|
|
result[i] = StarlarkToGo(val.Index(i))
|
|
}
|
|
return result
|
|
case *starlark.Dict:
|
|
return DictToMap(val)
|
|
case starlark.Tuple:
|
|
result := make([]any, len(val))
|
|
for i, e := range val {
|
|
result[i] = StarlarkToGo(e)
|
|
}
|
|
return result
|
|
default:
|
|
return v.String()
|
|
}
|
|
}
|
|
|
|
// DictToMap converts a *starlark.Dict to map[string]any.
|
|
// Non-string keys are silently skipped.
|
|
func DictToMap(d *starlark.Dict) map[string]any {
|
|
result := make(map[string]any, d.Len())
|
|
for _, item := range d.Items() {
|
|
k, ok := starlark.AsString(item[0])
|
|
if !ok {
|
|
continue
|
|
}
|
|
result[k] = StarlarkToGo(item[1])
|
|
}
|
|
return result
|
|
}
|
|
|
|
// MapToDict converts a map[string]any to *starlark.Dict.
|
|
func MapToDict(m map[string]any) *starlark.Dict {
|
|
d := starlark.NewDict(len(m))
|
|
for k, v := range m {
|
|
_ = d.SetKey(starlark.String(k), GoToStarlark(v))
|
|
}
|
|
return d
|
|
}
|