Fix some more minor bugs and tests

This commit is contained in:
2025-03-25 19:14:21 +01:00
parent 4640281fbf
commit 4eed05c7c2
2 changed files with 66 additions and 59 deletions

View File

@@ -2,7 +2,6 @@ package processor
import (
"fmt"
"strconv"
"strings"
lua "github.com/yuin/gopher-lua"
@@ -91,29 +90,31 @@ func ToLua(L *lua.LState, data interface{}) (lua.LValue, error) {
// FromLua converts a Lua table to a struct or map recursively
func FromLua(L *lua.LState, luaValue lua.LValue) (interface{}, error) {
switch v := luaValue.(type) {
// Well shit...
// Tables in lua are both maps and arrays
// As arrays they are ordered and as maps, obviously, not
// So when we parse them to a go map we fuck up the order for arrays
// We have to find a better way....
case *lua.LTable:
result := make(map[string]interface{})
v.ForEach(func(key lua.LValue, value lua.LValue) {
result[key.String()], _ = FromLua(L, value)
})
// This may be a bit wasteful...
// Hopefully it won't run often enough to matter
isArray := true
for key := range result {
_, err := strconv.Atoi(key)
if err != nil {
isArray = false
break
}
isArray, err := IsLuaTableArray(L, v)
if err != nil {
return nil, err
}
if isArray {
list := make([]interface{}, 0, len(result))
for _, value := range result {
list = append(list, value)
}
return list, nil
result := make([]interface{}, 0)
v.ForEach(func(key lua.LValue, value lua.LValue) {
converted, _ := FromLua(L, value)
result = append(result, converted)
})
return result, nil
} else {
result := make(map[string]interface{})
v.ForEach(func(key lua.LValue, value lua.LValue) {
converted, _ := FromLua(L, value)
result[key.String()] = converted
})
return result, nil
}
return result, nil
case lua.LString:
return string(v), nil
case lua.LBool:
@@ -125,6 +126,24 @@ func FromLua(L *lua.LState, luaValue lua.LValue) (interface{}, error) {
}
}
func IsLuaTableArray(L *lua.LState, v *lua.LTable) (bool, error) {
L.SetGlobal("table_to_check", v)
// Use our predefined helper function from InitLuaHelpers
err := L.DoString(`is_array = isArray(table_to_check)`)
if err != nil {
return false, fmt.Errorf("error determining if table is array: %w", err)
}
// Check the result of our Lua function
isArray := L.GetGlobal("is_array")
// LVIsFalse returns true if a given LValue is a nil or false otherwise false.
if !lua.LVIsFalse(isArray) {
return true, nil
}
return false, nil
}
// InitLuaHelpers initializes common Lua helper functions
func InitLuaHelpers(L *lua.LState) error {
helperScript := `
@@ -155,6 +174,20 @@ function is_number(str)
return tonumber(str) ~= nil
end
function isArray(t)
if type(t) ~= "table" then return false end
local max = 0
local count = 0
for k, _ in pairs(t) do
if type(k) ~= "number" or k < 1 or math.floor(k) ~= k then
return false
end
max = math.max(max, k)
count = count + 1
end
return max == count
end
modified = false
`
if err := L.DoString(helperScript); err != nil {