github.com/elves/elvish@v0.15.0/pkg/eval/vars/ptr.go (about) 1 package vars 2 3 import ( 4 "reflect" 5 "sync" 6 7 "github.com/elves/elvish/pkg/eval/vals" 8 ) 9 10 type PtrVar struct { 11 ptr interface{} 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 interface{}, 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 interface{}) 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 interface{}) 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() interface{} { 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() interface{} { 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 interface{}) error { 49 v.mutex.Lock() 50 defer v.mutex.Unlock() 51 return vals.ScanToGo(val, v.ptr) 52 }