Implement a generic translator between lua and go tables (maps)
This commit is contained in:
@@ -2,6 +2,7 @@ package processor
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
lua "github.com/yuin/gopher-lua"
|
lua "github.com/yuin/gopher-lua"
|
||||||
@@ -32,6 +33,86 @@ type ModificationRecord struct {
|
|||||||
Context string
|
Context string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewLuaState() (*lua.LState, error) {
|
||||||
|
L := lua.NewState()
|
||||||
|
// defer L.Close()
|
||||||
|
|
||||||
|
// Load math library
|
||||||
|
L.Push(L.GetGlobal("require"))
|
||||||
|
L.Push(lua.LString("math"))
|
||||||
|
if err := L.PCall(1, 1, nil); err != nil {
|
||||||
|
return nil, fmt.Errorf("error loading Lua math library: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize helper functions
|
||||||
|
if err := InitLuaHelpers(L); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return L, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToLuaTable converts a struct or map to a Lua table recursively
|
||||||
|
func ToLuaTable(L *lua.LState, data interface{}) (*lua.LTable, error) {
|
||||||
|
luaTable := L.NewTable()
|
||||||
|
|
||||||
|
switch v := data.(type) {
|
||||||
|
case map[string]interface{}:
|
||||||
|
for key, value := range v {
|
||||||
|
luaValue, err := ToLuaTable(L, value)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
luaTable.RawSetString(key, luaValue)
|
||||||
|
}
|
||||||
|
case struct{}:
|
||||||
|
val := reflect.ValueOf(v)
|
||||||
|
for i := 0; i < val.NumField(); i++ {
|
||||||
|
field := val.Type().Field(i)
|
||||||
|
luaValue, err := ToLuaTable(L, val.Field(i).Interface())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
luaTable.RawSetString(field.Name, luaValue)
|
||||||
|
}
|
||||||
|
case string:
|
||||||
|
luaTable.RawSetString("v", lua.LString(v))
|
||||||
|
case bool:
|
||||||
|
luaTable.RawSetString("v", lua.LBool(v))
|
||||||
|
case float64:
|
||||||
|
luaTable.RawSetString("v", lua.LNumber(v))
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unsupported data type: %T", data)
|
||||||
|
}
|
||||||
|
return luaTable, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromLuaTable converts a Lua table to a struct or map recursively
|
||||||
|
func FromLuaTable(L *lua.LState, luaTable *lua.LTable) (map[string]interface{}, error) {
|
||||||
|
result := make(map[string]interface{})
|
||||||
|
|
||||||
|
luaTable.ForEach(func(key lua.LValue, value lua.LValue) {
|
||||||
|
switch v := value.(type) {
|
||||||
|
case *lua.LTable:
|
||||||
|
nestedMap, err := FromLuaTable(L, v)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
result[key.String()] = nestedMap
|
||||||
|
case lua.LString:
|
||||||
|
result[key.String()] = string(v)
|
||||||
|
case lua.LBool:
|
||||||
|
result[key.String()] = bool(v)
|
||||||
|
case lua.LNumber:
|
||||||
|
result[key.String()] = float64(v)
|
||||||
|
default:
|
||||||
|
result[key.String()] = nil
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
// InitLuaHelpers initializes common Lua helper functions
|
// InitLuaHelpers initializes common Lua helper functions
|
||||||
func InitLuaHelpers(L *lua.LState) error {
|
func InitLuaHelpers(L *lua.LState) error {
|
||||||
helperScript := `
|
helperScript := `
|
||||||
|
Reference in New Issue
Block a user