github.com/terramate-io/tf@v0.0.0-20230830114523-fce866b4dfcd/addrs/map.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 package addrs 5 6 // Map represents a mapping whose keys are address types that implement 7 // UniqueKeyer. 8 // 9 // Since not all address types are comparable in the Go language sense, this 10 // type cannot work with the typical Go map access syntax, and so instead has 11 // a method-based syntax. Use this type only for situations where the key 12 // type isn't guaranteed to always be a valid key for a standard Go map. 13 type Map[K UniqueKeyer, V any] struct { 14 // Elems is the internal data structure of the map. 15 // 16 // This is exported to allow for comparisons during tests and other similar 17 // careful read operations, but callers MUST NOT modify this map directly. 18 // Use only the methods of Map to modify the contents of this structure, 19 // to ensure that it remains correct and consistent. 20 Elems map[UniqueKey]MapElem[K, V] 21 } 22 23 type MapElem[K UniqueKeyer, V any] struct { 24 Key K 25 Value V 26 } 27 28 func MakeMap[K UniqueKeyer, V any](initialElems ...MapElem[K, V]) Map[K, V] { 29 inner := make(map[UniqueKey]MapElem[K, V], len(initialElems)) 30 ret := Map[K, V]{inner} 31 for _, elem := range initialElems { 32 ret.Put(elem.Key, elem.Value) 33 } 34 return ret 35 } 36 37 func MakeMapElem[K UniqueKeyer, V any](key K, value V) MapElem[K, V] { 38 return MapElem[K, V]{key, value} 39 } 40 41 // Put inserts a new element into the map, or replaces an existing element 42 // which has an equivalent key. 43 func (m Map[K, V]) Put(key K, value V) { 44 realKey := key.UniqueKey() 45 m.Elems[realKey] = MapElem[K, V]{key, value} 46 } 47 48 // PutElement is like Put but takes the key and value from the given MapElement 49 // structure instead of as individual arguments. 50 func (m Map[K, V]) PutElement(elem MapElem[K, V]) { 51 m.Put(elem.Key, elem.Value) 52 } 53 54 // Remove deletes the element with the given key from the map, or does nothing 55 // if there is no such element. 56 func (m Map[K, V]) Remove(key K) { 57 realKey := key.UniqueKey() 58 delete(m.Elems, realKey) 59 } 60 61 // Get returns the value of the element with the given key, or the zero value 62 // of V if there is no such element. 63 func (m Map[K, V]) Get(key K) V { 64 realKey := key.UniqueKey() 65 return m.Elems[realKey].Value 66 } 67 68 // GetOk is like Get but additionally returns a flag for whether there was an 69 // element with the given key present in the map. 70 func (m Map[K, V]) GetOk(key K) (V, bool) { 71 realKey := key.UniqueKey() 72 elem, ok := m.Elems[realKey] 73 return elem.Value, ok 74 } 75 76 // Has returns true if and only if there is an element in the map which has the 77 // given key. 78 func (m Map[K, V]) Has(key K) bool { 79 realKey := key.UniqueKey() 80 _, ok := m.Elems[realKey] 81 return ok 82 } 83 84 // Len returns the number of elements in the map. 85 func (m Map[K, V]) Len() int { 86 return len(m.Elems) 87 } 88 89 // Elements returns a slice containing a snapshot of the current elements of 90 // the map, in an unpredictable order. 91 func (m Map[K, V]) Elements() []MapElem[K, V] { 92 if len(m.Elems) == 0 { 93 return nil 94 } 95 ret := make([]MapElem[K, V], 0, len(m.Elems)) 96 for _, elem := range m.Elems { 97 ret = append(ret, elem) 98 } 99 return ret 100 } 101 102 // Keys returns a Set[K] containing a snapshot of the current keys of elements 103 // of the map. 104 func (m Map[K, V]) Keys() Set[K] { 105 if len(m.Elems) == 0 { 106 return nil 107 } 108 ret := make(Set[K], len(m.Elems)) 109 110 // We mess with the internals of Set here, rather than going through its 111 // public interface, because that means we can avoid re-calling UniqueKey 112 // on all of the elements when we know that our own Put method would have 113 // already done the same thing. 114 for realKey, elem := range m.Elems { 115 ret[realKey] = elem.Key 116 } 117 return ret 118 } 119 120 // Values returns a slice containing a snapshot of the current values of 121 // elements of the map, in an unpredictable order. 122 func (m Map[K, V]) Values() []V { 123 if len(m.Elems) == 0 { 124 return nil 125 } 126 ret := make([]V, 0, len(m.Elems)) 127 for _, elem := range m.Elems { 128 ret = append(ret, elem.Value) 129 } 130 return ret 131 }