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 }