362f447d9f
* cmd/statreceiver: lua-scriptable stat receiver Change-Id: I3ce0fe3f1ef4b1f4f27eed90bac0e91cfecf22d7 * some updates Change-Id: I7c3485adcda1278fce01ae077b4761b3ddb9fb7a * more comments Change-Id: I0bb22993cd934c3d40fc1da80d07e49e686b80dd * linter fixes Change-Id: Ied014304ecb9aadcf00a6b66ad28f856a428d150 * catch errors Change-Id: I6e1920f1fd941e66199b30bc427285c19769fc70 * review feedback Change-Id: I9d4051851eab18970c5f5ddcf4ff265508e541d3 * errorgroup improvements Change-Id: I4699dda3022f0485fbb50c9dafe692d3921734ff * too tricky the previous thing was better for memory with lots of errors at a time but https://play.golang.org/p/RweTMRjoSCt is too much of a foot gun Change-Id: I23f0b3d77dd4288fcc20b3756a7110359576bf44
86 lines
1.9 KiB
Go
86 lines
1.9 KiB
Go
// Copyright (C) 2018 Storj Labs, Inc.
|
|
// See LICENSE for copying information.
|
|
|
|
package luacfg
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"io/ioutil"
|
|
"sync"
|
|
|
|
lua "github.com/Shopify/go-lua"
|
|
luar "github.com/jtolds/go-luar"
|
|
)
|
|
|
|
// Scope represents a collection of values registered in a Lua namespace.
|
|
type Scope struct {
|
|
mtx sync.Mutex
|
|
registrations map[string]func(*lua.State) error
|
|
}
|
|
|
|
// NewScope creates an empty Scope.
|
|
func NewScope() *Scope {
|
|
return &Scope{
|
|
registrations: map[string]func(*lua.State) error{},
|
|
}
|
|
}
|
|
|
|
// RegisterType allows you to add a Lua function that creates new
|
|
// values of the given type to the scope.
|
|
func (s *Scope) RegisterType(name string, example interface{}) error {
|
|
return s.register(name, example, luar.PushType)
|
|
}
|
|
|
|
// RegisterVal adds the Go value 'value', including Go functions, to the Lua
|
|
// scope.
|
|
func (s *Scope) RegisterVal(name string, value interface{}) error {
|
|
return s.register(name, value, luar.PushValue)
|
|
}
|
|
|
|
func (s *Scope) register(name string, val interface{},
|
|
pusher func(l *lua.State, val interface{}) error) error {
|
|
s.mtx.Lock()
|
|
defer s.mtx.Unlock()
|
|
if _, exists := s.registrations[name]; exists {
|
|
return fmt.Errorf("Registration %#v already exists", name)
|
|
}
|
|
s.registrations[name] = func(l *lua.State) error {
|
|
err := pusher(l, val)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
l.SetGlobal(name)
|
|
return nil
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Run runs the Lua source represented by in
|
|
func (s *Scope) Run(in io.Reader) error {
|
|
l := lua.NewState()
|
|
luar.SetOptions(l, luar.Options{AllowUnexportedAccess: true})
|
|
|
|
s.mtx.Lock()
|
|
registrations := make([]func(l *lua.State) error, 0, len(s.registrations))
|
|
for _, reg := range s.registrations {
|
|
registrations = append(registrations, reg)
|
|
}
|
|
s.mtx.Unlock()
|
|
|
|
for _, reg := range registrations {
|
|
err := reg(l)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
data, err := ioutil.ReadAll(in)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = lua.DoString(l, string(data))
|
|
return err
|
|
}
|