diff options
author | appilon <apilon@hashicorp.com> | 2019-02-27 16:43:31 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-02-27 16:43:31 -0500 |
commit | 844b5a68d8af4791755b8f0ad293cc99f5959183 (patch) | |
tree | 255c250a5c9d4801c74092d33b7337d8c14438ff /vendor/github.com/zclconf/go-cty/cty/set_internals.go | |
parent | 303b299eeb6b06e939e35905e4b34cb410dd9dc3 (diff) | |
parent | 15c0b25d011f37e7c20aeca9eaf461f78285b8d9 (diff) | |
download | terraform-provider-statuscake-844b5a68d8af4791755b8f0ad293cc99f5959183.tar.gz terraform-provider-statuscake-844b5a68d8af4791755b8f0ad293cc99f5959183.tar.zst terraform-provider-statuscake-844b5a68d8af4791755b8f0ad293cc99f5959183.zip |
Merge pull request #27 from terraform-providers/go-modules-2019-02-22
[MODULES] Switch to Go Modules
Diffstat (limited to 'vendor/github.com/zclconf/go-cty/cty/set_internals.go')
-rw-r--r-- | vendor/github.com/zclconf/go-cty/cty/set_internals.go | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/vendor/github.com/zclconf/go-cty/cty/set_internals.go b/vendor/github.com/zclconf/go-cty/cty/set_internals.go new file mode 100644 index 0000000..ce738db --- /dev/null +++ b/vendor/github.com/zclconf/go-cty/cty/set_internals.go | |||
@@ -0,0 +1,146 @@ | |||
1 | package cty | ||
2 | |||
3 | import ( | ||
4 | "bytes" | ||
5 | "fmt" | ||
6 | "hash/crc32" | ||
7 | "math/big" | ||
8 | "sort" | ||
9 | ) | ||
10 | |||
11 | // setRules provides a Rules implementation for the ./set package that | ||
12 | // respects the equality rules for cty values of the given type. | ||
13 | // | ||
14 | // This implementation expects that values added to the set will be | ||
15 | // valid internal values for the given Type, which is to say that wrapping | ||
16 | // the given value in a Value struct along with the ruleset's type should | ||
17 | // produce a valid, working Value. | ||
18 | type setRules struct { | ||
19 | Type Type | ||
20 | } | ||
21 | |||
22 | func (r setRules) Hash(v interface{}) int { | ||
23 | hashBytes := makeSetHashBytes(Value{ | ||
24 | ty: r.Type, | ||
25 | v: v, | ||
26 | }) | ||
27 | return int(crc32.ChecksumIEEE(hashBytes)) | ||
28 | } | ||
29 | |||
30 | func (r setRules) Equivalent(v1 interface{}, v2 interface{}) bool { | ||
31 | v1v := Value{ | ||
32 | ty: r.Type, | ||
33 | v: v1, | ||
34 | } | ||
35 | v2v := Value{ | ||
36 | ty: r.Type, | ||
37 | v: v2, | ||
38 | } | ||
39 | |||
40 | eqv := v1v.Equals(v2v) | ||
41 | |||
42 | // By comparing the result to true we ensure that an Unknown result, | ||
43 | // which will result if either value is unknown, will be considered | ||
44 | // as non-equivalent. Two unknown values are not equivalent for the | ||
45 | // sake of set membership. | ||
46 | return eqv.v == true | ||
47 | } | ||
48 | |||
49 | func makeSetHashBytes(val Value) []byte { | ||
50 | var buf bytes.Buffer | ||
51 | appendSetHashBytes(val, &buf) | ||
52 | return buf.Bytes() | ||
53 | } | ||
54 | |||
55 | func appendSetHashBytes(val Value, buf *bytes.Buffer) { | ||
56 | // Exactly what bytes we generate here don't matter as long as the following | ||
57 | // constraints hold: | ||
58 | // - Unknown and null values all generate distinct strings from | ||
59 | // each other and from any normal value of the given type. | ||
60 | // - The delimiter used to separate items in a compound structure can | ||
61 | // never appear literally in any of its elements. | ||
62 | // Since we don't support hetrogenous lists we don't need to worry about | ||
63 | // collisions between values of different types, apart from | ||
64 | // PseudoTypeDynamic. | ||
65 | // If in practice we *do* get a collision then it's not a big deal because | ||
66 | // the Equivalent function will still distinguish values, but set | ||
67 | // performance will be best if we are able to produce a distinct string | ||
68 | // for each distinct value, unknown values notwithstanding. | ||
69 | if !val.IsKnown() { | ||
70 | buf.WriteRune('?') | ||
71 | return | ||
72 | } | ||
73 | if val.IsNull() { | ||
74 | buf.WriteRune('~') | ||
75 | return | ||
76 | } | ||
77 | |||
78 | switch val.ty { | ||
79 | case Number: | ||
80 | buf.WriteString(val.v.(*big.Float).String()) | ||
81 | return | ||
82 | case Bool: | ||
83 | if val.v.(bool) { | ||
84 | buf.WriteRune('T') | ||
85 | } else { | ||
86 | buf.WriteRune('F') | ||
87 | } | ||
88 | return | ||
89 | case String: | ||
90 | buf.WriteString(fmt.Sprintf("%q", val.v.(string))) | ||
91 | return | ||
92 | } | ||
93 | |||
94 | if val.ty.IsMapType() { | ||
95 | buf.WriteRune('{') | ||
96 | val.ForEachElement(func(keyVal, elementVal Value) bool { | ||
97 | appendSetHashBytes(keyVal, buf) | ||
98 | buf.WriteRune(':') | ||
99 | appendSetHashBytes(elementVal, buf) | ||
100 | buf.WriteRune(';') | ||
101 | return false | ||
102 | }) | ||
103 | buf.WriteRune('}') | ||
104 | return | ||
105 | } | ||
106 | |||
107 | if val.ty.IsListType() || val.ty.IsSetType() { | ||
108 | buf.WriteRune('[') | ||
109 | val.ForEachElement(func(keyVal, elementVal Value) bool { | ||
110 | appendSetHashBytes(elementVal, buf) | ||
111 | buf.WriteRune(';') | ||
112 | return false | ||
113 | }) | ||
114 | buf.WriteRune(']') | ||
115 | return | ||
116 | } | ||
117 | |||
118 | if val.ty.IsObjectType() { | ||
119 | buf.WriteRune('<') | ||
120 | attrNames := make([]string, 0, len(val.ty.AttributeTypes())) | ||
121 | for attrName := range val.ty.AttributeTypes() { | ||
122 | attrNames = append(attrNames, attrName) | ||
123 | } | ||
124 | sort.Strings(attrNames) | ||
125 | for _, attrName := range attrNames { | ||
126 | appendSetHashBytes(val.GetAttr(attrName), buf) | ||
127 | buf.WriteRune(';') | ||
128 | } | ||
129 | buf.WriteRune('>') | ||
130 | return | ||
131 | } | ||
132 | |||
133 | if val.ty.IsTupleType() { | ||
134 | buf.WriteRune('<') | ||
135 | val.ForEachElement(func(keyVal, elementVal Value) bool { | ||
136 | appendSetHashBytes(elementVal, buf) | ||
137 | buf.WriteRune(';') | ||
138 | return false | ||
139 | }) | ||
140 | buf.WriteRune('>') | ||
141 | return | ||
142 | } | ||
143 | |||
144 | // should never get down here | ||
145 | panic("unsupported type in set hash") | ||
146 | } | ||