Implement a generic translator between lua and go tables (maps)
This commit is contained in:
@@ -2,6 +2,7 @@ package processor
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
lua "github.com/yuin/gopher-lua"
|
||||
@@ -32,6 +33,86 @@ type ModificationRecord struct {
|
||||
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
|
||||
func InitLuaHelpers(L *lua.LState) error {
|
||||
helperScript := `
|
||||
|
Reference in New Issue
Block a user