Files
obitools4/pkg/obilua/lua_table.go
T
Eric Coissac da0c8b6f28 ♻️ refactor lua_push_interface and add json module
Refactor pushInterfaceToLua to delegate unsupported types (nil, bool/int/float/string/map/slice) recursively via new lvalueFromInterface helper. Simplify typed slice and map handlers, remove explicit nil case (now handled by lvalueFromInterface), eliminate redundant type switches in pushMapStringIntToLua and similar functions. Add new luajson.go with RegisterJSON, lua.JSONEncode/Decode bindings using lvalueFromInterface and Table2 Interface for bidirectional round-trips. Include comprehensive tests covering scalars, nested structures (e.g., kmindex response), arrays and error cases.
2026-04-13 17:56:58 +02:00

122 lines
2.7 KiB
Go

package obilua
import (
log "github.com/sirupsen/logrus"
lua "github.com/yuin/gopher-lua"
)
func Table2Interface(interpreter *lua.LState, table *lua.LTable) interface{} {
// <EC> 07/03/2024: il y a sans doute plus efficace mais pour l'instant
// ça marche
isArray := true
table.ForEach(func(key, value lua.LValue) {
if _, ok := key.(lua.LNumber); !ok {
isArray = false
}
})
if isArray {
val := make([]interface{}, table.Len())
for i := 1; i <= table.Len(); i++ {
v := table.RawGetInt(i)
switch v.Type() {
case lua.LTNil:
val[i-1] = nil
case lua.LTBool:
val[i-1] = bool(v.(lua.LBool))
case lua.LTNumber:
val[i-1] = float64(v.(lua.LNumber))
case lua.LTString:
val[i-1] = string(v.(lua.LString))
case lua.LTTable:
val[i-1] = Table2Interface(interpreter, v.(*lua.LTable))
}
}
return val
} else {
// The table contains a hash
val := make(map[string]interface{})
table.ForEach(func(k, v lua.LValue) {
if ks, ok := k.(lua.LString); ok {
switch v.Type() {
case lua.LTNil:
val[string(ks)] = nil
case lua.LTBool:
val[string(ks)] = bool(v.(lua.LBool))
case lua.LTNumber:
val[string(ks)] = float64(v.(lua.LNumber))
case lua.LTString:
val[string(ks)] = string(v.(lua.LString))
case lua.LTTable:
val[string(ks)] = Table2Interface(interpreter, v.(*lua.LTable))
}
}
})
return val
}
}
func Table2ByteSlice(interpreter *lua.LState, table *lua.LTable) []byte {
isArray := true
table.ForEach(func(key, value lua.LValue) {
if _, ok := key.(lua.LNumber); !ok {
isArray = false
}
})
if isArray {
val := make([]byte, table.Len())
for i := 1; i <= table.Len(); i++ {
v := table.RawGetInt(i)
switch v.Type() {
case lua.LTNumber:
if x := float64(v.(lua.LNumber)); x <= 255 {
val[i-1] = byte(x)
} else {
log.Fatalf("LUA: Value %f at index %d is to large to be converted to byte", x, i)
}
default:
log.Fatalf("LUA: Value %v at index %d cannot be converted to byte", v, i)
}
}
return val
}
log.Fatalf("LUA: Value %v cannot be converted to []byte", table)
return nil
}
// }
// return nil
// }
// if x := table.RawGetInt(1); x != nil {
// val := make([]interface{}, table.Len())
// for i := 1; i <= table.Len(); i++ {
// val[i-1] = table.RawGetInt(i)
// }
// return val
// } else {
// }
// }
// if lv.Type() == lua.LTTable {
// table := lv.(*lua.LTable)
// isArray := true
// table.ForEach(func(key, value lua.LValue) {
// if _, ok := key.(lua.LNumber); !ok {
// isArray = false
// }
// })
// if isArray {
// // The table contains an array
// } else {
// // The table contains a hash
// }
// }