opentofu/internal/addrs/set.go
Martin Atkins eb2374070f addrs: Generic types for maps and sets of addresses
The addrs.Set type previously snuck in accidentally as part of the work
to add addrs.UniqueKey and addrs.UniqueKeyer, because without support for
generic types the addrs.Set type was a bit of a safety hazard due to not
being able to enforce particular address types at compile time.

However, with Go 1.18 adding support for type parameters we can now turn
addrs.Set into a generic type over any specific addrs.UniqueKeyer type,
and complement it with an addrs.Map type which supports addrs.UniqueKeyer
keys as a way to encapsulate the handling of maps with UniqueKey keys that
we currently do inline in various other parts of Terraform.

This doesn't yet introduce any callers of these types, but we'll convert
existing users of addrs.UniqueKeyer gradually in subsequent commits.
2022-06-16 07:03:36 -07:00

60 lines
1.7 KiB
Go

package addrs
// Set represents a set of addresses of types that implement UniqueKeyer.
//
// Modify the set only by the methods on this type. This type exposes its
// internals for convenience during reading, such as iterating over set elements
// by ranging over the map values, but making direct modifications could
// potentially make the set data invalid or inconsistent, leading to undefined
// behavior elsewhere.
type Set[T UniqueKeyer] map[UniqueKey]UniqueKeyer
// Has returns true if and only if the set includes the given address.
func (s Set[T]) Has(addr UniqueKeyer) bool {
_, exists := s[addr.UniqueKey()]
return exists
}
// Add inserts the given address into the set, if not already present. If
// an equivalent address is already in the set, this replaces that address
// with the new value.
func (s Set[T]) Add(addr UniqueKeyer) {
s[addr.UniqueKey()] = addr
}
// Remove deletes the given address from the set, if present. If not present,
// this is a no-op.
func (s Set[T]) Remove(addr UniqueKeyer) {
delete(s, addr.UniqueKey())
}
// Union returns a new set which contains the union of all of the elements
// of both the reciever and the given other set.
func (s Set[T]) Union(other Set[T]) Set[T] {
ret := make(Set[T])
for k, addr := range s {
ret[k] = addr
}
for k, addr := range other {
ret[k] = addr
}
return ret
}
// Intersection returns a new set which contains the intersection of all of the
// elements of both the reciever and the given other set.
func (s Set[T]) Intersection(other Set[T]) Set[T] {
ret := make(Set[T])
for k, addr := range s {
if _, exists := other[k]; exists {
ret[k] = addr
}
}
for k, addr := range other {
if _, exists := s[k]; exists {
ret[k] = addr
}
}
return ret
}