aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/zclconf/go-cty/cty/function/stdlib/collection.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/zclconf/go-cty/cty/function/stdlib/collection.go')
-rw-r--r--vendor/github.com/zclconf/go-cty/cty/function/stdlib/collection.go140
1 files changed, 140 insertions, 0 deletions
diff --git a/vendor/github.com/zclconf/go-cty/cty/function/stdlib/collection.go b/vendor/github.com/zclconf/go-cty/cty/function/stdlib/collection.go
new file mode 100644
index 0000000..967ba03
--- /dev/null
+++ b/vendor/github.com/zclconf/go-cty/cty/function/stdlib/collection.go
@@ -0,0 +1,140 @@
1package stdlib
2
3import (
4 "fmt"
5
6 "github.com/zclconf/go-cty/cty"
7 "github.com/zclconf/go-cty/cty/function"
8 "github.com/zclconf/go-cty/cty/gocty"
9)
10
11var HasIndexFunc = function.New(&function.Spec{
12 Params: []function.Parameter{
13 {
14 Name: "collection",
15 Type: cty.DynamicPseudoType,
16 AllowDynamicType: true,
17 },
18 {
19 Name: "key",
20 Type: cty.DynamicPseudoType,
21 AllowDynamicType: true,
22 },
23 },
24 Type: func(args []cty.Value) (ret cty.Type, err error) {
25 collTy := args[0].Type()
26 if !(collTy.IsTupleType() || collTy.IsListType() || collTy.IsMapType() || collTy == cty.DynamicPseudoType) {
27 return cty.NilType, fmt.Errorf("collection must be a list, a map or a tuple")
28 }
29 return cty.Bool, nil
30 },
31 Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
32 return args[0].HasIndex(args[1]), nil
33 },
34})
35
36var IndexFunc = function.New(&function.Spec{
37 Params: []function.Parameter{
38 {
39 Name: "collection",
40 Type: cty.DynamicPseudoType,
41 },
42 {
43 Name: "key",
44 Type: cty.DynamicPseudoType,
45 AllowDynamicType: true,
46 },
47 },
48 Type: func(args []cty.Value) (ret cty.Type, err error) {
49 collTy := args[0].Type()
50 key := args[1]
51 keyTy := key.Type()
52 switch {
53 case collTy.IsTupleType():
54 if keyTy != cty.Number && keyTy != cty.DynamicPseudoType {
55 return cty.NilType, fmt.Errorf("key for tuple must be number")
56 }
57 if !key.IsKnown() {
58 return cty.DynamicPseudoType, nil
59 }
60 var idx int
61 err := gocty.FromCtyValue(key, &idx)
62 if err != nil {
63 return cty.NilType, fmt.Errorf("invalid key for tuple: %s", err)
64 }
65
66 etys := collTy.TupleElementTypes()
67
68 if idx >= len(etys) || idx < 0 {
69 return cty.NilType, fmt.Errorf("key must be between 0 and %d inclusive", len(etys))
70 }
71
72 return etys[idx], nil
73
74 case collTy.IsListType():
75 if keyTy != cty.Number && keyTy != cty.DynamicPseudoType {
76 return cty.NilType, fmt.Errorf("key for list must be number")
77 }
78
79 return collTy.ElementType(), nil
80
81 case collTy.IsMapType():
82 if keyTy != cty.String && keyTy != cty.DynamicPseudoType {
83 return cty.NilType, fmt.Errorf("key for map must be string")
84 }
85
86 return collTy.ElementType(), nil
87
88 default:
89 return cty.NilType, fmt.Errorf("collection must be a list, a map or a tuple")
90 }
91 },
92 Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
93 has, err := HasIndex(args[0], args[1])
94 if err != nil {
95 return cty.NilVal, err
96 }
97 if has.False() { // safe because collection and key are guaranteed known here
98 return cty.NilVal, fmt.Errorf("invalid index")
99 }
100
101 return args[0].Index(args[1]), nil
102 },
103})
104
105var LengthFunc = function.New(&function.Spec{
106 Params: []function.Parameter{
107 {
108 Name: "collection",
109 Type: cty.DynamicPseudoType,
110 AllowDynamicType: true,
111 },
112 },
113 Type: func(args []cty.Value) (ret cty.Type, err error) {
114 collTy := args[0].Type()
115 if !(collTy.IsTupleType() || collTy.IsListType() || collTy.IsMapType() || collTy.IsSetType() || collTy == cty.DynamicPseudoType) {
116 return cty.NilType, fmt.Errorf("collection must be a list, a map or a tuple")
117 }
118 return cty.Number, nil
119 },
120 Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
121 return args[0].Length(), nil
122 },
123})
124
125// HasIndex determines whether the given collection can be indexed with the
126// given key.
127func HasIndex(collection cty.Value, key cty.Value) (cty.Value, error) {
128 return HasIndexFunc.Call([]cty.Value{collection, key})
129}
130
131// Index returns an element from the given collection using the given key,
132// or returns an error if there is no element for the given key.
133func Index(collection cty.Value, key cty.Value) (cty.Value, error) {
134 return IndexFunc.Call([]cty.Value{collection, key})
135}
136
137// Length returns the number of elements in the given collection.
138func Length(collection cty.Value) (cty.Value, error) {
139 return LengthFunc.Call([]cty.Value{collection})
140}