github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/internal/k8s/jsonpath/value.go (about)

     1  package jsonpath
     2  
     3  import "reflect"
     4  
     5  // A wrapper around reflect.Value that allows callers
     6  // to call Set() on a Value retrieved from inside a map index.
     7  //
     8  // In the normal reflect package, the value in a map index
     9  // is not addressable, because the internal map implementation
    10  // might have to rearrange the map storage.
    11  //
    12  // In this implementation, we keep an extra reference to the
    13  // map that "owns" the value, so that we can call Set() on it.
    14  type Value struct {
    15  	reflect.Value
    16  	parentMap    reflect.Value
    17  	parentMapKey reflect.Value
    18  }
    19  
    20  func Wrap(v reflect.Value) Value {
    21  	return Value{Value: v}
    22  }
    23  
    24  func ValueOf(v interface{}) Value {
    25  	return Value{Value: reflect.ValueOf(v)}
    26  }
    27  
    28  func (v Value) CanSet() bool {
    29  	if v.parentMap != (reflect.Value{}) {
    30  		return true
    31  	}
    32  	return v.Value.CanSet()
    33  }
    34  
    35  func (v *Value) Set(newV reflect.Value) {
    36  	if v.parentMap != (reflect.Value{}) {
    37  		v.parentMap.SetMapIndex(v.parentMapKey, newV)
    38  		v.Value = newV
    39  		return
    40  	}
    41  	v.Value.Set(newV)
    42  }
    43  
    44  func (v *Value) Sibling(name string) (val Value, ok bool) {
    45  	if !v.parentMap.IsValid() {
    46  		return Value{}, false
    47  	}
    48  
    49  	key := reflect.ValueOf(name)
    50  	sib := v.parentMap.MapIndex(key)
    51  	if !sib.IsValid() {
    52  		return Value{}, false
    53  	}
    54  
    55  	return Value{
    56  		Value:        sib,
    57  		parentMap:    v.parentMap,
    58  		parentMapKey: key,
    59  	}, true
    60  }