aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/zclconf/go-cty/cty/value_init.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/zclconf/go-cty/cty/value_init.go')
-rw-r--r--vendor/github.com/zclconf/go-cty/cty/value_init.go276
1 files changed, 276 insertions, 0 deletions
diff --git a/vendor/github.com/zclconf/go-cty/cty/value_init.go b/vendor/github.com/zclconf/go-cty/cty/value_init.go
new file mode 100644
index 0000000..495a83e
--- /dev/null
+++ b/vendor/github.com/zclconf/go-cty/cty/value_init.go
@@ -0,0 +1,276 @@
1package cty
2
3import (
4 "fmt"
5 "math/big"
6 "reflect"
7
8 "golang.org/x/text/unicode/norm"
9
10 "github.com/zclconf/go-cty/cty/set"
11)
12
13// BoolVal returns a Value of type Number whose internal value is the given
14// bool.
15func BoolVal(v bool) Value {
16 return Value{
17 ty: Bool,
18 v: v,
19 }
20}
21
22// NumberVal returns a Value of type Number whose internal value is the given
23// big.Float. The returned value becomes the owner of the big.Float object,
24// and so it's forbidden for the caller to mutate the object after it's
25// wrapped in this way.
26func NumberVal(v *big.Float) Value {
27 return Value{
28 ty: Number,
29 v: v,
30 }
31}
32
33// NumberIntVal returns a Value of type Number whose internal value is equal
34// to the given integer.
35func NumberIntVal(v int64) Value {
36 return NumberVal(new(big.Float).SetInt64(v))
37}
38
39// NumberUIntVal returns a Value of type Number whose internal value is equal
40// to the given unsigned integer.
41func NumberUIntVal(v uint64) Value {
42 return NumberVal(new(big.Float).SetUint64(v))
43}
44
45// NumberFloatVal returns a Value of type Number whose internal value is
46// equal to the given float.
47func NumberFloatVal(v float64) Value {
48 return NumberVal(new(big.Float).SetFloat64(v))
49}
50
51// StringVal returns a Value of type String whose internal value is the
52// given string.
53//
54// Strings must be UTF-8 encoded sequences of valid unicode codepoints, and
55// they are NFC-normalized on entry into the world of cty values.
56//
57// If the given string is not valid UTF-8 then behavior of string operations
58// is undefined.
59func StringVal(v string) Value {
60 return Value{
61 ty: String,
62 v: NormalizeString(v),
63 }
64}
65
66// NormalizeString applies the same normalization that cty applies when
67// constructing string values.
68//
69// A return value from this function can be meaningfully compared byte-for-byte
70// with a Value.AsString result.
71func NormalizeString(s string) string {
72 return norm.NFC.String(s)
73}
74
75// ObjectVal returns a Value of an object type whose structure is defined
76// by the key names and value types in the given map.
77func ObjectVal(attrs map[string]Value) Value {
78 attrTypes := make(map[string]Type, len(attrs))
79 attrVals := make(map[string]interface{}, len(attrs))
80
81 for attr, val := range attrs {
82 attr = NormalizeString(attr)
83 attrTypes[attr] = val.ty
84 attrVals[attr] = val.v
85 }
86
87 return Value{
88 ty: Object(attrTypes),
89 v: attrVals,
90 }
91}
92
93// TupleVal returns a Value of a tuple type whose element types are
94// defined by the value types in the given slice.
95func TupleVal(elems []Value) Value {
96 elemTypes := make([]Type, len(elems))
97 elemVals := make([]interface{}, len(elems))
98
99 for i, val := range elems {
100 elemTypes[i] = val.ty
101 elemVals[i] = val.v
102 }
103
104 return Value{
105 ty: Tuple(elemTypes),
106 v: elemVals,
107 }
108}
109
110// ListVal returns a Value of list type whose element type is defined by
111// the types of the given values, which must be homogenous.
112//
113// If the types are not all consistent (aside from elements that are of the
114// dynamic pseudo-type) then this function will panic. It will panic also
115// if the given list is empty, since then the element type cannot be inferred.
116// (See also ListValEmpty.)
117func ListVal(vals []Value) Value {
118 if len(vals) == 0 {
119 panic("must not call ListVal with empty slice")
120 }
121 elementType := DynamicPseudoType
122 rawList := make([]interface{}, len(vals))
123
124 for i, val := range vals {
125 if elementType == DynamicPseudoType {
126 elementType = val.ty
127 } else if val.ty != DynamicPseudoType && !elementType.Equals(val.ty) {
128 panic(fmt.Errorf(
129 "inconsistent list element types (%#v then %#v)",
130 elementType, val.ty,
131 ))
132 }
133
134 rawList[i] = val.v
135 }
136
137 return Value{
138 ty: List(elementType),
139 v: rawList,
140 }
141}
142
143// ListValEmpty returns an empty list of the given element type.
144func ListValEmpty(element Type) Value {
145 return Value{
146 ty: List(element),
147 v: []interface{}{},
148 }
149}
150
151// MapVal returns a Value of a map type whose element type is defined by
152// the types of the given values, which must be homogenous.
153//
154// If the types are not all consistent (aside from elements that are of the
155// dynamic pseudo-type) then this function will panic. It will panic also
156// if the given map is empty, since then the element type cannot be inferred.
157// (See also MapValEmpty.)
158func MapVal(vals map[string]Value) Value {
159 if len(vals) == 0 {
160 panic("must not call MapVal with empty map")
161 }
162 elementType := DynamicPseudoType
163 rawMap := make(map[string]interface{}, len(vals))
164
165 for key, val := range vals {
166 if elementType == DynamicPseudoType {
167 elementType = val.ty
168 } else if val.ty != DynamicPseudoType && !elementType.Equals(val.ty) {
169 panic(fmt.Errorf(
170 "inconsistent map element types (%#v then %#v)",
171 elementType, val.ty,
172 ))
173 }
174
175 rawMap[NormalizeString(key)] = val.v
176 }
177
178 return Value{
179 ty: Map(elementType),
180 v: rawMap,
181 }
182}
183
184// MapValEmpty returns an empty map of the given element type.
185func MapValEmpty(element Type) Value {
186 return Value{
187 ty: Map(element),
188 v: map[string]interface{}{},
189 }
190}
191
192// SetVal returns a Value of set type whose element type is defined by
193// the types of the given values, which must be homogenous.
194//
195// If the types are not all consistent (aside from elements that are of the
196// dynamic pseudo-type) then this function will panic. It will panic also
197// if the given list is empty, since then the element type cannot be inferred.
198// (See also SetValEmpty.)
199func SetVal(vals []Value) Value {
200 if len(vals) == 0 {
201 panic("must not call SetVal with empty slice")
202 }
203 elementType := DynamicPseudoType
204 rawList := make([]interface{}, len(vals))
205
206 for i, val := range vals {
207 if elementType == DynamicPseudoType {
208 elementType = val.ty
209 } else if val.ty != DynamicPseudoType && !elementType.Equals(val.ty) {
210 panic(fmt.Errorf(
211 "inconsistent set element types (%#v then %#v)",
212 elementType, val.ty,
213 ))
214 }
215
216 rawList[i] = val.v
217 }
218
219 rawVal := set.NewSetFromSlice(setRules{elementType}, rawList)
220
221 return Value{
222 ty: Set(elementType),
223 v: rawVal,
224 }
225}
226
227// SetValFromValueSet returns a Value of set type based on an already-constructed
228// ValueSet.
229//
230// The element type of the returned value is the element type of the given
231// set.
232func SetValFromValueSet(s ValueSet) Value {
233 ety := s.ElementType()
234 rawVal := s.s.Copy() // copy so caller can't mutate what we wrap
235
236 return Value{
237 ty: Set(ety),
238 v: rawVal,
239 }
240}
241
242// SetValEmpty returns an empty set of the given element type.
243func SetValEmpty(element Type) Value {
244 return Value{
245 ty: Set(element),
246 v: set.NewSet(setRules{element}),
247 }
248}
249
250// CapsuleVal creates a value of the given capsule type using the given
251// wrapVal, which must be a pointer to a value of the capsule type's native
252// type.
253//
254// This function will panic if the given type is not a capsule type, if
255// the given wrapVal is not compatible with the given capsule type, or if
256// wrapVal is not a pointer.
257func CapsuleVal(ty Type, wrapVal interface{}) Value {
258 if !ty.IsCapsuleType() {
259 panic("not a capsule type")
260 }
261
262 wv := reflect.ValueOf(wrapVal)
263 if wv.Kind() != reflect.Ptr {
264 panic("wrapVal is not a pointer")
265 }
266
267 it := ty.typeImpl.(*capsuleType).GoType
268 if !wv.Type().Elem().AssignableTo(it) {
269 panic("wrapVal target is not compatible with the given capsule type")
270 }
271
272 return Value{
273 ty: ty,
274 v: wrapVal,
275 }
276}