/
starlark_struct.go
95 lines (79 loc) · 2.51 KB
/
starlark_struct.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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
// Copyright 2024 The Carvel Authors.
// SPDX-License-Identifier: Apache-2.0
package core
import (
"fmt"
"carvel.dev/ytt/pkg/orderedmap"
"github.com/k14s/starlark-go/starlark"
)
type StarlarkStruct struct {
data *orderedmap.Map // [string]starlark.Value; most common usage: HasAttrs
}
func NewStarlarkStruct(goStringKeyToStarlarkValue *orderedmap.Map) *StarlarkStruct {
return &StarlarkStruct{data: goStringKeyToStarlarkValue}
}
var _ starlark.Value = (*StarlarkStruct)(nil)
var _ starlark.HasAttrs = (*StarlarkStruct)(nil)
var _ starlark.IterableMapping = (*StarlarkStruct)(nil)
var _ starlark.Sequence = (*StarlarkStruct)(nil)
func (s *StarlarkStruct) String() string { return "struct(...)" }
func (s *StarlarkStruct) Type() string { return "struct" }
func (s *StarlarkStruct) Freeze() {} // TODO
func (s *StarlarkStruct) Truth() starlark.Bool { return s.data.Len() > 0 }
func (s *StarlarkStruct) Hash() (uint32, error) { return 0, fmt.Errorf("unhashable type: struct") }
func (s *StarlarkStruct) Len() int { return s.data.Len() }
// returns (nil, nil) if attribute not present
func (s *StarlarkStruct) Attr(name string) (starlark.Value, error) {
val, found := s.data.Get(name)
if found {
return val.(starlark.Value), nil
}
return nil, nil
}
// callers must not modify the result.
func (s *StarlarkStruct) AttrNames() []string {
var keys []string
s.data.Iterate(func(key, _ interface{}) {
keys = append(keys, key.(string))
})
return keys
}
func (s *StarlarkStruct) Get(key starlark.Value) (val starlark.Value, found bool, err error) {
attrName, err := NewStarlarkValue(key).AsString()
if err != nil {
return starlark.None, false, err
}
value, found := s.data.Get(attrName)
if found {
return value.(starlark.Value), true, nil
}
return starlark.None, false, nil
}
func (s *StarlarkStruct) Iterate() starlark.Iterator {
return &StarlarkStructIterator{
keys: s.data.Keys(),
}
}
func (s *StarlarkStruct) Items() (items []starlark.Tuple) {
s.data.Iterate(func(key, val interface{}) {
items = append(items, starlark.Tuple{
NewGoValue(key).AsStarlarkValue(),
val.(starlark.Value),
})
})
return
}
type StarlarkStructIterator struct {
keys []interface{}
idx int
}
var _ starlark.Iterator = &StarlarkStructIterator{}
func (s *StarlarkStructIterator) Next(p *starlark.Value) bool {
if s.idx < len(s.keys) {
*p = NewGoValue(s.keys[s.idx]).AsStarlarkValue()
s.idx++
return true
}
return false
}
func (s *StarlarkStructIterator) Done() { /* intentionally blank. */ }