-
Notifications
You must be signed in to change notification settings - Fork 11
/
world_reflect_table.go
154 lines (137 loc) · 5.35 KB
/
world_reflect_table.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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
package rbxmk
import (
"fmt"
lua "github.com/anaminus/gopher-lua"
"github.com/robloxapi/types"
)
// PushToTable reflects v according to its type as registered with s.World, then
// sets the result to table[field]. The type must be single-value. Does nothing
// if v is nil.
func (w *World) PushToTable(table *lua.LTable, field lua.LValue, v types.Value) (err error) {
if v == nil {
return
}
push, err := w.PusherOf(v.Type())
if err != nil {
return err
}
lv, err := push(w.Context(), v)
if err != nil {
return fmt.Errorf("field %s: %w", field, err)
}
table.RawSet(field, lv)
return nil
}
// PullFromTable gets a value from table[field], and reflects a value from it to
// type t registered with s.World.
func (w *World) PullFromTable(table *lua.LTable, field lua.LValue, t string) (v types.Value, err error) {
pull, err := w.PullerOf(t)
if err != nil {
return nil, err
}
if v, err = pull(w.Context(), table.RawGet(field)); err != nil {
return nil, fmt.Errorf("field %s: %w", field, err)
}
return v, nil
}
// PullFromTableOpt gets a value from table[field], and reflects a value from it
// to type t registered with s.World. If the value is nil, d is returned
// instead.
func (w *World) PullFromTableOpt(table *lua.LTable, field lua.LValue, d types.Value, t string) (v types.Value, err error) {
pull, err := w.PullerOf(t)
if err != nil {
return nil, err
}
lv := table.RawGet(field)
if lv == lua.LNil {
return d, nil
}
if v, err = pull(w.Context(), lv); err != nil {
return nil, fmt.Errorf("field %s: %w", field, err)
}
return v, nil
}
// PullAnyFromTable gets a value from table[field], and reflects a value from it
// according to the first successful type from t registered with s.World.
func (w *World) PullAnyFromTable(table *lua.LTable, field lua.LValue, t ...string) (v types.Value, err error) {
lv := table.RawGet(field)
for _, t := range t {
pull, err := w.PullerOf(t)
if err != nil {
return nil, err
}
if v, err := pull(w.Context(), lv); err == nil {
return v, nil
}
}
return nil, fmt.Errorf("field %s: %s expected, got %s", field, w.ListTypes(t), w.Typeof(lv))
}
// PullAnyFromTableOpt gets a value from table[field], and reflects a value from
// it according to the first successful type from t registered with s.World. If
// the field is nil, then d is returned instead.
func (w *World) PullAnyFromTableOpt(table *lua.LTable, field lua.LValue, d types.Value, t ...string) (v types.Value, err error) {
lv := table.RawGet(field)
if lv == lua.LNil {
return d, nil
}
for _, t := range t {
pull, err := w.PullerOf(t)
if err != nil {
return nil, err
}
if v, err := pull(w.Context(), lv); err == nil {
return v, nil
}
}
return nil, fmt.Errorf("field %s: %s expected, got %s", field, w.ListTypes(t), w.Typeof(lv))
}
// PushToArray is like PushToTable, but receives an int as the index of the
// table.
func (w *World) PushToArray(table *lua.LTable, index int, v types.Value) (err error) {
return w.PushToTable(table, lua.LNumber(index), v)
}
// PullFromArray is like PullFromTable, but receives an int as the index of the
// table.
func (w *World) PullFromArray(table *lua.LTable, index int, t string) (v types.Value, err error) {
return w.PullFromTable(table, lua.LNumber(index), t)
}
// PullFromArrayOpt is like PullFromTableOpt, but receives an int as the index
// of the table.
func (w *World) PullFromArrayOpt(table *lua.LTable, index int, d types.Value, t string) (v types.Value, err error) {
return w.PullFromTableOpt(table, lua.LNumber(index), d, t)
}
// PullAnyFromArray is like PullAnyFromTable, but receives an int as the index
// of the table.
func (w *World) PullAnyFromArray(table *lua.LTable, index int, t ...string) (v types.Value, err error) {
return w.PullAnyFromTable(table, lua.LNumber(index), t...)
}
// PullAnyFromArrayOpt is like PullAnyFromTableOpt, but receives an int as the
// index of the table.
func (w *World) PullAnyFromArrayOpt(table *lua.LTable, index int, d types.Value, t ...string) (v types.Value, err error) {
return w.PullAnyFromTableOpt(table, lua.LNumber(index), v, t...)
}
// PushToDictionary is like PushToTable, but receives a string as the key of the
// table.
func (w *World) PushToDictionary(table *lua.LTable, key string, v types.Value) (err error) {
return w.PushToTable(table, lua.LString(key), v)
}
// PullFromDictionary is like PullFromTable, but receives a string as the key of
// the table.
func (w *World) PullFromDictionary(table *lua.LTable, key string, t string) (v types.Value, err error) {
return w.PullFromTable(table, lua.LString(key), t)
}
// PullFromDictionaryOpt is like PullFromTableOpt, but receives a string as the
// key of the table.
func (w *World) PullFromDictionaryOpt(table *lua.LTable, key string, d types.Value, t string) (v types.Value, err error) {
return w.PullFromTableOpt(table, lua.LString(key), d, t)
}
// PullAnyFromDictionary is like PullAnyFromTable, but receives a string as the
// key of the table.
func (w *World) PullAnyFromDictionary(table *lua.LTable, key string, t ...string) (v types.Value, err error) {
return w.PullAnyFromTable(table, lua.LString(key), t...)
}
// PullAnyFromDictionaryOpt is like PullAnyFromTableOpt, but receives a string
// as the key of the table.
func (w *World) PullAnyFromDictionaryOpt(table *lua.LTable, key string, d types.Value, t ...string) (v types.Value, err error) {
return w.PullAnyFromTableOpt(table, lua.LString(key), v, t...)
}