github.com/rajeev159/opa@v0.45.0/ast/map.go (about) 1 // Copyright 2016 The OPA Authors. All rights reserved. 2 // Use of this source code is governed by an Apache2 3 // license that can be found in the LICENSE file. 4 5 package ast 6 7 import ( 8 "encoding/json" 9 10 "github.com/open-policy-agent/opa/util" 11 ) 12 13 // ValueMap represents a key/value map between AST term values. Any type of term 14 // can be used as a key in the map. 15 type ValueMap struct { 16 hashMap *util.HashMap 17 } 18 19 // NewValueMap returns a new ValueMap. 20 func NewValueMap() *ValueMap { 21 vs := &ValueMap{ 22 hashMap: util.NewHashMap(valueEq, valueHash), 23 } 24 return vs 25 } 26 27 // MarshalJSON provides a custom marshaller for the ValueMap which 28 // will include the key, value, and value type. 29 func (vs *ValueMap) MarshalJSON() ([]byte, error) { 30 var tmp []map[string]interface{} 31 vs.Iter(func(k Value, v Value) bool { 32 tmp = append(tmp, map[string]interface{}{ 33 "name": k.String(), 34 "type": TypeName(v), 35 "value": v, 36 }) 37 return false 38 }) 39 return json.Marshal(tmp) 40 } 41 42 // Copy returns a shallow copy of the ValueMap. 43 func (vs *ValueMap) Copy() *ValueMap { 44 if vs == nil { 45 return nil 46 } 47 cpy := NewValueMap() 48 cpy.hashMap = vs.hashMap.Copy() 49 return cpy 50 } 51 52 // Equal returns true if this ValueMap equals the other. 53 func (vs *ValueMap) Equal(other *ValueMap) bool { 54 if vs == nil { 55 return other == nil || other.Len() == 0 56 } 57 if other == nil { 58 return vs == nil || vs.Len() == 0 59 } 60 return vs.hashMap.Equal(other.hashMap) 61 } 62 63 // Len returns the number of elements in the map. 64 func (vs *ValueMap) Len() int { 65 if vs == nil { 66 return 0 67 } 68 return vs.hashMap.Len() 69 } 70 71 // Get returns the value in the map for k. 72 func (vs *ValueMap) Get(k Value) Value { 73 if vs != nil { 74 if v, ok := vs.hashMap.Get(k); ok { 75 return v.(Value) 76 } 77 } 78 return nil 79 } 80 81 // Hash returns a hash code for this ValueMap. 82 func (vs *ValueMap) Hash() int { 83 if vs == nil { 84 return 0 85 } 86 return vs.hashMap.Hash() 87 } 88 89 // Iter calls the iter function for each key/value pair in the map. If the iter 90 // function returns true, iteration stops. 91 func (vs *ValueMap) Iter(iter func(Value, Value) bool) bool { 92 if vs == nil { 93 return false 94 } 95 return vs.hashMap.Iter(func(kt, vt util.T) bool { 96 k := kt.(Value) 97 v := vt.(Value) 98 return iter(k, v) 99 }) 100 } 101 102 // Put inserts a key k into the map with value v. 103 func (vs *ValueMap) Put(k, v Value) { 104 if vs == nil { 105 panic("put on nil value map") 106 } 107 vs.hashMap.Put(k, v) 108 } 109 110 // Delete removes a key k from the map. 111 func (vs *ValueMap) Delete(k Value) { 112 if vs == nil { 113 return 114 } 115 vs.hashMap.Delete(k) 116 } 117 118 func (vs *ValueMap) String() string { 119 if vs == nil { 120 return "{}" 121 } 122 return vs.hashMap.String() 123 } 124 125 func valueHash(v util.T) int { 126 return v.(Value).Hash() 127 } 128 129 func valueEq(a, b util.T) bool { 130 av := a.(Value) 131 bv := b.(Value) 132 return av.Compare(bv) == 0 133 }