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  }