-
Notifications
You must be signed in to change notification settings - Fork 393
/
cfg.go
87 lines (72 loc) · 1.99 KB
/
cfg.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
// Copyright (C) 2019 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 {
mu 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 (scope *Scope) RegisterType(name string, example interface{}) error {
return scope.register(name, example, luar.PushType)
}
// RegisterVal adds the Go value 'value', including Go functions, to the Lua
// scope.
func (scope *Scope) RegisterVal(name string, value interface{}) error {
return scope.register(name, value, luar.PushValue)
}
func (scope *Scope) register(name string, val interface{}, pusher func(l *lua.State, val interface{}) error) error {
scope.mu.Lock()
defer scope.mu.Unlock()
if _, exists := scope.registrations[name]; exists {
return fmt.Errorf("registration %#v already exists", name)
}
scope.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 (scope *Scope) Run(in io.Reader) error {
l := lua.NewState()
lua.OpenLibraries(l)
luar.SetOptions(l, luar.Options{AllowUnexportedAccess: true})
scope.mu.Lock()
registrations := make([]func(l *lua.State) error, 0, len(scope.registrations))
for _, reg := range scope.registrations {
registrations = append(registrations, reg)
}
scope.mu.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
}