mirror of
https://github.com/go-sylixos/elvish.git
synced 2024-12-15 20:17:50 +08:00
136 lines
2.4 KiB
Go
136 lines
2.4 KiB
Go
package eval
|
|
|
|
import (
|
|
"errors"
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
var (
|
|
ErrRoCannotBeSet = errors.New("read-only; cannot be set")
|
|
)
|
|
|
|
// Variable represents an elvish variable.
|
|
type Variable interface {
|
|
Set(v Value)
|
|
Get() Value
|
|
}
|
|
|
|
type ptrVariable struct {
|
|
valuePtr *Value
|
|
validator func(Value) error
|
|
}
|
|
|
|
func NewPtrVariable(v Value) Variable {
|
|
return NewPtrVariableWithValidator(v, nil)
|
|
}
|
|
|
|
func NewPtrVariableWithValidator(v Value, vld func(Value) error) Variable {
|
|
return ptrVariable{&v, vld}
|
|
}
|
|
|
|
func (iv ptrVariable) Set(val Value) {
|
|
if iv.validator != nil {
|
|
if err := iv.validator(val); err != nil {
|
|
throw(errors.New("invalid value: " + err.Error()))
|
|
}
|
|
}
|
|
*iv.valuePtr = val
|
|
}
|
|
|
|
func (iv ptrVariable) Get() Value {
|
|
return *iv.valuePtr
|
|
}
|
|
|
|
type roVariable struct {
|
|
value Value
|
|
}
|
|
|
|
func NewRoVariable(v Value) Variable {
|
|
return roVariable{v}
|
|
}
|
|
|
|
func (rv roVariable) Set(val Value) {
|
|
throw(ErrRoCannotBeSet)
|
|
}
|
|
|
|
func (rv roVariable) Get() Value {
|
|
return rv.value
|
|
}
|
|
|
|
type cbVariable struct {
|
|
set func(Value)
|
|
get func() Value
|
|
}
|
|
|
|
// MakeVariableFromCallback makes a variable from a set callback and a get
|
|
// callback.
|
|
func MakeVariableFromCallback(set func(Value), get func() Value) Variable {
|
|
return &cbVariable{set, get}
|
|
}
|
|
|
|
func (cv *cbVariable) Set(val Value) {
|
|
cv.set(val)
|
|
}
|
|
|
|
func (cv *cbVariable) Get() Value {
|
|
return cv.get()
|
|
}
|
|
|
|
type roCbVariable func() Value
|
|
|
|
// MakeRoVariableFromCallback makes a read-only variable from a get callback.
|
|
func MakeRoVariableFromCallback(get func() Value) Variable {
|
|
return roCbVariable(get)
|
|
}
|
|
|
|
func (cv roCbVariable) Set(Value) {
|
|
throw(ErrRoCannotBeSet)
|
|
}
|
|
|
|
func (cv roCbVariable) Get() Value {
|
|
return cv()
|
|
}
|
|
|
|
// elemVariable is an element of a IndexSetter.
|
|
type elemVariable struct {
|
|
container IndexSetter
|
|
index Value
|
|
}
|
|
|
|
func (ev elemVariable) Set(val Value) {
|
|
ev.container.IndexSet(ev.index, val)
|
|
}
|
|
|
|
func (ev elemVariable) Get() Value {
|
|
return ev.container.IndexOne(ev.index)
|
|
}
|
|
|
|
type envVariable struct {
|
|
name string
|
|
}
|
|
|
|
func newEnvVariable(name string) envVariable {
|
|
return envVariable{name}
|
|
}
|
|
|
|
func (ev envVariable) Set(val Value) {
|
|
os.Setenv(ev.name, ToString(val))
|
|
}
|
|
|
|
func (ev envVariable) Get() Value {
|
|
return String(os.Getenv(ev.name))
|
|
}
|
|
|
|
type pathEnvVariable struct {
|
|
envVariable
|
|
ppaths *[]string
|
|
}
|
|
|
|
func (pev pathEnvVariable) Set(val Value) {
|
|
s := ToString(val)
|
|
os.Setenv(pev.name, s)
|
|
paths := strings.Split(s, ":")
|
|
*pev.ppaths = paths
|
|
}
|