src.elv.sh@v0.21.0-dev.0.20240515223629-06979efb9a2a/pkg/eval/vars/ptr.go (about) 1 package vars 2 3 import ( 4 "reflect" 5 "sync" 6 7 "src.elv.sh/pkg/eval/vals" 8 ) 9 10 type PtrVar struct { 11 ptr any 12 mutex *sync.RWMutex 13 } 14 15 // FromPtrWithMutex creates a variable from a pointer. The variable is kept in 16 // sync with the value the pointer points to, converting with vals.ScanToGo and 17 // vals.FromGo when Get and Set. Its access is guarded by the supplied mutex. 18 func FromPtrWithMutex(p any, m *sync.RWMutex) PtrVar { 19 return PtrVar{p, m} 20 } 21 22 // FromPtr creates a variable from a pointer. The variable is kept in sync with 23 // the value the pointer points to, converting with vals.ScanToGo and 24 // vals.FromGo when Get and Set. Its access is guarded by a new mutex. 25 func FromPtr(p any) PtrVar { 26 return FromPtrWithMutex(p, new(sync.RWMutex)) 27 } 28 29 // FromInit creates a variable with an initial value. The variable created 30 // can be assigned values of any type. 31 func FromInit(v any) Var { 32 return FromPtr(&v) 33 } 34 35 // Get returns the value pointed by the pointer, after conversion using FromGo. 36 func (v PtrVar) Get() any { 37 return vals.FromGo(v.GetRaw()) 38 } 39 40 // GetRaw returns the value pointed by the pointer without any conversion. 41 func (v PtrVar) GetRaw() any { 42 v.mutex.RLock() 43 defer v.mutex.RUnlock() 44 return reflect.Indirect(reflect.ValueOf(v.ptr)).Interface() 45 } 46 47 // Set sets the value pointed by the pointer, after conversion using ScanToGo. 48 func (v PtrVar) Set(val any) error { 49 v.mutex.Lock() 50 defer v.mutex.Unlock() 51 return vals.ScanToGo(val, v.ptr) 52 }