github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/internal/tiltfile/encoding/starlark.go (about) 1 package encoding 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "strings" 7 8 "github.com/pkg/errors" 9 "go.starlark.net/starlark" 10 ) 11 12 func ConvertStructuredDataToStarlark(j interface{}) (starlark.Value, error) { 13 switch j := j.(type) { 14 case bool: 15 return starlark.Bool(j), nil 16 case string: 17 return starlark.String(j), nil 18 case json.Number: 19 if strings.Contains(j.String(), ".") { 20 f, err := j.Float64() 21 if err != nil { 22 return nil, err 23 } 24 return starlark.Float(f), nil 25 } else { 26 i, err := j.Int64() 27 if err != nil { 28 return nil, err 29 } 30 return starlark.MakeInt64(i), nil 31 } 32 case int64: 33 return starlark.MakeInt64(j), nil 34 case float64: 35 return starlark.Float(j), nil 36 case []interface{}: 37 listOfValues := []starlark.Value{} 38 39 for _, v := range j { 40 convertedValue, err := ConvertStructuredDataToStarlark(v) 41 if err != nil { 42 return nil, err 43 } 44 listOfValues = append(listOfValues, convertedValue) 45 } 46 47 return starlark.NewList(listOfValues), nil 48 case map[string]interface{}: 49 mapOfValues := &starlark.Dict{} 50 51 for k, v := range j { 52 convertedValue, err := ConvertStructuredDataToStarlark(v) 53 if err != nil { 54 return nil, err 55 } 56 57 err = mapOfValues.SetKey(starlark.String(k), convertedValue) 58 if err != nil { 59 return nil, err 60 } 61 } 62 63 return mapOfValues, nil 64 case nil: 65 return starlark.None, nil 66 } 67 68 return nil, errors.New(fmt.Sprintf("Unable to convert to starlark value, unexpected type %T", j)) 69 } 70 71 func convertStarlarkToStructuredData(v starlark.Value) (interface{}, error) { 72 switch v := v.(type) { 73 case starlark.Bool: 74 return bool(v), nil 75 case starlark.String: 76 return v.GoString(), nil 77 case starlark.Int: 78 return v.BigInt().Int64(), nil 79 case starlark.Float: 80 return float64(v), nil 81 case *starlark.List: 82 ret := []interface{}{} 83 84 it := v.Iterate() 85 defer it.Done() 86 var e starlark.Value 87 for it.Next(&e) { 88 ee, err := convertStarlarkToStructuredData(e) 89 if err != nil { 90 return nil, err 91 } 92 ret = append(ret, ee) 93 } 94 return ret, nil 95 case *starlark.Dict: 96 ret := make(map[string]interface{}) 97 for _, t := range v.Items() { 98 key := t.Index(0) 99 kk, err := convertStarlarkToStructuredData(key) 100 if err != nil { 101 return nil, err 102 } 103 104 s, ok := kk.(string) 105 if !ok { 106 return nil, fmt.Errorf("only string keys are supported in maps. found key '%s' of type %T", key.String(), kk) 107 } 108 109 val := t.Index(1) 110 vv, err := convertStarlarkToStructuredData(val) 111 if err != nil { 112 return nil, err 113 } 114 115 ret[s] = vv 116 } 117 118 return ret, nil 119 case starlark.NoneType: 120 return nil, nil 121 } 122 123 return nil, fmt.Errorf("unable to convert from starlark value, unsupported type %T", v) 124 }