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  }