verstak/internal/core/plugins/api_utils.go

93 lines
2.2 KiB
Go

package plugins
import (
"fmt"
lua "github.com/yuin/gopher-lua"
)
// pushError pushes an error message as a Lua error (using lua.Errorf-style).
// Returns 0 (no return values — the Lua function will error).
func pushError(L *lua.LState, err error) int {
L.RaiseError("%s", err.Error())
return 0 // unreachable, but satisfies signature
}
// pushResult pushes a single value to Lua stack and returns 1.
func pushResult(L *lua.LState, val lua.LValue) int {
L.Push(val)
return 1
}
// pushOK pushes true (success) to Lua stack.
func pushOK(L *lua.LState) int {
L.Push(lua.LBool(true))
return 1
}
// checkOptString gets an optional string argument at position.
func checkOptString(L *lua.LState, pos int, defaultVal string) string {
if L.GetTop() >= pos {
return L.CheckString(pos)
}
return defaultVal
}
// checkOptInt gets an optional int argument at position.
func checkOptInt(L *lua.LState, pos int, defaultVal int) int {
if L.GetTop() >= pos {
return L.CheckInt(pos)
}
return defaultVal
}
// checkOptTable gets an optional table argument at position.
func checkOptTable(L *lua.LState, pos int) *lua.LTable {
if L.GetTop() >= pos && L.Get(pos).Type() == lua.LTTable {
return L.CheckTable(pos)
}
return nil
}
// tableToMap converts a Lua table to map[string]interface{}.
// Only handles string keys and basic value types.
func tableToMap(tbl *lua.LTable) map[string]interface{} {
m := make(map[string]interface{})
tbl.ForEach(func(key lua.LValue, val lua.LValue) {
k := lua.LVAsString(key)
m[k] = luaValueToGo(val)
})
return m
}
// luaValueToGo converts a Lua value to a Go interface{}.
func luaValueToGo(v lua.LValue) interface{} {
if v == lua.LNil {
return nil
}
switch val := v.(type) {
case lua.LBool:
return bool(val)
case lua.LString:
return string(val)
case lua.LNumber:
return float64(val)
case *lua.LTable:
// Detect if it's an array or map
if val.MaxN() > 0 {
arr := make([]interface{}, 0, val.MaxN())
for i := 1; i <= val.MaxN(); i++ {
arr = append(arr, luaValueToGo(val.RawGetInt(i)))
}
return arr
}
m := make(map[string]interface{})
val.ForEach(func(k lua.LValue, v lua.LValue) {
m[fmt.Sprintf("%v", k)] = luaValueToGo(v)
})
return m
default:
return fmt.Sprintf("%v", v)
}
}