mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-25 18:45:20 -06:00
We introduced the addrs.UniqueKey and addrs.UniqueKeyer mechanics as part of implementing the ValidateMoves and ApplyMoves functions, as a way to better encapsulate the solution to the problem that lots of our address types aren't comparable and so cannot be used directly as map keys. However, exposing addrs.UniqueKey handling directly in the logic adds various noise to the algorithms and, in particular, obscures the fact that MoveResults.Changes and MoveResult.Blocked both have different map key types. Here then we'll use the new addrs.Map helper type, which encapsulates the idea of a map from an addrs.UniqueKeyer type to an arbitrary value type, using the unique keys as the map keys internally. This does unfortunately mean that we lose the conventional Go map access syntax and have to use a method-based API instead, but I (subjectively) think that's an okay compromise in return for avoiding the need to keep track inline of which addrs.UniqueKey values correspond with which real addresses. This is intended as an entirely-mechanical change, with equivalent behavior to what it replaced. If anything here is doing something materially different than what it replaced then that's a mistake.
60 lines
1.7 KiB
Go
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]T
|
|
|
|
// Has returns true if and only if the set includes the given address.
|
|
func (s Set[T]) Has(addr T) 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 T) {
|
|
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 T) {
|
|
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
|
|
}
|