diff options
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.go | 276 |
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 @@ | |||
1 | package cty | ||
2 | |||
3 | import ( | ||
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. | ||
15 | func 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. | ||
26 | func 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. | ||
35 | func 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. | ||
41 | func 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. | ||
47 | func 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. | ||
59 | func 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. | ||
71 | func 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. | ||
77 | func 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. | ||
95 | func 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.) | ||
117 | func 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. | ||
144 | func 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.) | ||
158 | func 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. | ||
185 | func 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.) | ||
199 | func 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. | ||
232 | func 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. | ||
243 | func 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. | ||
257 | func 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 | } | ||