]>
Commit | Line | Data |
---|---|---|
15c0b25d AP |
1 | package cty |
2 | ||
3 | import ( | |
4 | "fmt" | |
5 | ||
6 | "github.com/zclconf/go-cty/cty/set" | |
7 | ) | |
8 | ||
9 | // ValueSet is to cty.Set what []cty.Value is to cty.List and | |
10 | // map[string]cty.Value is to cty.Map. It's provided to allow callers a | |
11 | // convenient interface for manipulating sets before wrapping them in cty.Set | |
12 | // values using cty.SetValFromValueSet. | |
13 | // | |
14 | // Unlike value slices and value maps, ValueSet instances have a single | |
15 | // homogenous element type because that is a requirement of the underlying | |
16 | // set implementation, which uses the element type to select a suitable | |
17 | // hashing function. | |
18 | // | |
19 | // Set mutations are not concurrency-safe. | |
20 | type ValueSet struct { | |
21 | // ValueSet is just a thin wrapper around a set.Set with our value-oriented | |
22 | // "rules" applied. We do this so that the caller can work in terms of | |
23 | // cty.Value objects even though the set internals use the raw values. | |
24 | s set.Set | |
25 | } | |
26 | ||
27 | // NewValueSet creates and returns a new ValueSet with the given element type. | |
28 | func NewValueSet(ety Type) ValueSet { | |
29 | return newValueSet(set.NewSet(setRules{Type: ety})) | |
30 | } | |
31 | ||
32 | func newValueSet(s set.Set) ValueSet { | |
33 | return ValueSet{ | |
34 | s: s, | |
35 | } | |
36 | } | |
37 | ||
38 | // ElementType returns the element type for the receiving ValueSet. | |
39 | func (s ValueSet) ElementType() Type { | |
40 | return s.s.Rules().(setRules).Type | |
41 | } | |
42 | ||
43 | // Add inserts the given value into the receiving set. | |
44 | func (s ValueSet) Add(v Value) { | |
45 | s.requireElementType(v) | |
46 | s.s.Add(v.v) | |
47 | } | |
48 | ||
49 | // Remove deletes the given value from the receiving set, if indeed it was | |
50 | // there in the first place. If the value is not present, this is a no-op. | |
51 | func (s ValueSet) Remove(v Value) { | |
52 | s.requireElementType(v) | |
53 | s.s.Remove(v.v) | |
54 | } | |
55 | ||
56 | // Has returns true if the given value is in the receiving set, or false if | |
57 | // it is not. | |
58 | func (s ValueSet) Has(v Value) bool { | |
59 | s.requireElementType(v) | |
60 | return s.s.Has(v.v) | |
61 | } | |
62 | ||
63 | // Copy performs a shallow copy of the receiving set, returning a new set | |
64 | // with the same rules and elements. | |
65 | func (s ValueSet) Copy() ValueSet { | |
66 | return newValueSet(s.s.Copy()) | |
67 | } | |
68 | ||
69 | // Length returns the number of values in the set. | |
70 | func (s ValueSet) Length() int { | |
71 | return s.s.Length() | |
72 | } | |
73 | ||
74 | // Values returns a slice of all of the values in the set in no particular | |
75 | // order. | |
76 | func (s ValueSet) Values() []Value { | |
77 | l := s.s.Length() | |
78 | if l == 0 { | |
79 | return nil | |
80 | } | |
81 | ret := make([]Value, 0, l) | |
82 | ety := s.ElementType() | |
83 | for it := s.s.Iterator(); it.Next(); { | |
84 | ret = append(ret, Value{ | |
85 | ty: ety, | |
86 | v: it.Value(), | |
87 | }) | |
88 | } | |
89 | return ret | |
90 | } | |
91 | ||
92 | // Union returns a new set that contains all of the members of both the | |
93 | // receiving set and the given set. Both sets must have the same element type, | |
94 | // or else this function will panic. | |
95 | func (s ValueSet) Union(other ValueSet) ValueSet { | |
96 | return newValueSet(s.s.Union(other.s)) | |
97 | } | |
98 | ||
99 | // Intersection returns a new set that contains the values that both the | |
100 | // receiver and given sets have in common. Both sets must have the same element | |
101 | // type, or else this function will panic. | |
102 | func (s ValueSet) Intersection(other ValueSet) ValueSet { | |
103 | return newValueSet(s.s.Intersection(other.s)) | |
104 | } | |
105 | ||
106 | // Subtract returns a new set that contains all of the values from the receiver | |
107 | // that are not also in the given set. Both sets must have the same element | |
108 | // type, or else this function will panic. | |
109 | func (s ValueSet) Subtract(other ValueSet) ValueSet { | |
110 | return newValueSet(s.s.Subtract(other.s)) | |
111 | } | |
112 | ||
113 | // SymmetricDifference returns a new set that contains all of the values from | |
114 | // both the receiver and given sets, except those that both sets have in | |
115 | // common. Both sets must have the same element type, or else this function | |
116 | // will panic. | |
117 | func (s ValueSet) SymmetricDifference(other ValueSet) ValueSet { | |
118 | return newValueSet(s.s.SymmetricDifference(other.s)) | |
119 | } | |
120 | ||
121 | // requireElementType panics if the given value is not of the set's element type. | |
122 | func (s ValueSet) requireElementType(v Value) { | |
123 | if !v.Type().Equals(s.ElementType()) { | |
124 | panic(fmt.Errorf("attempt to use %#v value with set of %#v", v.Type(), s.ElementType())) | |
125 | } | |
126 | } |