2024-03-06 12:56:44 -03:00
package obilua
import (
2024-09-03 06:08:07 -03:00
"sync"
2024-03-08 21:39:05 +01:00
log "github.com/sirupsen/logrus"
2024-03-06 12:56:44 -03:00
lua "github.com/yuin/gopher-lua"
)
// pushInterfaceToLua converts a Go interface{} value to an equivalent Lua value and pushes it onto the stack.
//
// L *lua.LState: the Lua state onto which the value will be pushed.
// val interface{}: the Go interface value to be converted and pushed. This can be a basic type such as string, bool, int, float64,
// or slices and maps of these basic types. Custom complex types will be converted to userdata with a predefined metatable.
//
// No return values. This function operates directly on the Lua state stack.
func pushInterfaceToLua ( L * lua . LState , val interface { } ) {
switch v := val . ( type ) {
case string :
L . Push ( lua . LString ( v ) )
case bool :
L . Push ( lua . LBool ( v ) )
case int :
L . Push ( lua . LNumber ( v ) )
case float64 :
L . Push ( lua . LNumber ( v ) )
// Add other cases as needed for different types
case map [ string ] int :
pushMapStringIntToLua ( L , v )
case map [ string ] string :
pushMapStringStringToLua ( L , v )
case map [ string ] bool :
pushMapStringBoolToLua ( L , v )
case map [ string ] float64 :
pushMapStringFloat64ToLua ( L , v )
2024-03-08 21:39:05 +01:00
case map [ string ] interface { } :
pushMapStringInterfaceToLua ( L , v )
2024-03-06 12:56:44 -03:00
case [ ] string :
pushSliceStringToLua ( L , v )
case [ ] int :
2024-04-13 12:40:43 +02:00
pushSliceNumericToLua ( L , v )
case [ ] byte :
pushSliceNumericToLua ( L , v )
2024-03-06 12:56:44 -03:00
case [ ] float64 :
2024-04-13 12:40:43 +02:00
pushSliceNumericToLua ( L , v )
2024-03-06 12:56:44 -03:00
case [ ] bool :
pushSliceBoolToLua ( L , v )
case nil :
L . Push ( lua . LNil )
2024-09-03 06:08:07 -03:00
case * sync . Mutex :
pushMutexToLua ( L , v )
2024-03-06 12:56:44 -03:00
default :
2024-04-13 12:40:43 +02:00
log . Fatalf ( "Cannot deal with value (%T) : %v" , val , val )
2024-03-06 12:56:44 -03:00
}
}
2024-03-08 21:39:05 +01:00
func pushMapStringInterfaceToLua ( L * lua . LState , m map [ string ] interface { } ) {
// Create a new Lua table
luaTable := L . NewTable ( )
// Iterate over the Go map and set the key-value pairs in the Lua table
for key , value := range m {
switch v := value . ( type ) {
case int :
luaTable . RawSetString ( key , lua . LNumber ( v ) )
case float64 :
luaTable . RawSetString ( key , lua . LNumber ( v ) )
case bool :
luaTable . RawSetString ( key , lua . LBool ( v ) )
case string :
luaTable . RawSetString ( key , lua . LString ( v ) )
default :
2024-03-12 17:18:29 +01:00
log . Fatalf ( "Doesn't deal with map containing value %v of type %T" , v , v )
2024-03-08 21:39:05 +01:00
}
}
// Push the Lua table onto the stack
L . Push ( luaTable )
}
2024-03-06 12:56:44 -03:00
// pushMapStringIntToLua creates a new Lua table and iterates over the Go map to set key-value pairs in the Lua table. It then pushes the Lua table onto the stack.
//
// L *lua.LState - the Lua state
// m map[string]int - the Go map containing string to int key-value pairs
func pushMapStringIntToLua ( L * lua . LState , m map [ string ] int ) {
// Create a new Lua table
luaTable := L . NewTable ( )
// Iterate over the Go map and set the key-value pairs in the Lua table
for key , value := range m {
2024-03-08 21:39:05 +01:00
L . SetTable ( luaTable , lua . LString ( key ) , lua . LNumber ( value ) )
2024-03-06 12:56:44 -03:00
}
// Push the Lua table onto the stack
L . Push ( luaTable )
}
// pushMapStringStringToLua creates a new Lua table and sets key-value pairs from the Go map, then pushes the Lua table onto the stack.
//
// L *lua.LState, m map[string]string. No return value.
func pushMapStringStringToLua ( L * lua . LState , m map [ string ] string ) {
// Create a new Lua table
luaTable := L . NewTable ( )
// Iterate over the Go map and set the key-value pairs in the Lua table
for key , value := range m {
2024-03-08 21:39:05 +01:00
L . SetTable ( luaTable , lua . LString ( key ) , lua . LString ( value ) )
2024-03-06 12:56:44 -03:00
}
// Push the Lua table onto the stack
L . Push ( luaTable )
}
// pushMapStringBoolToLua creates a new Lua table, iterates over the Go map, sets the key-value pairs in the Lua table, and then pushes the Lua table onto the stack.
//
// Parameters:
//
// L *lua.LState - the Lua state
// m map[string]bool - the Go map
//
// Return type(s): None
func pushMapStringBoolToLua ( L * lua . LState , m map [ string ] bool ) {
// Create a new Lua table
luaTable := L . NewTable ( )
// Iterate over the Go map and set the key-value pairs in the Lua table
for key , value := range m {
2024-03-08 21:39:05 +01:00
L . SetTable ( luaTable , lua . LString ( key ) , lua . LBool ( value ) )
2024-03-06 12:56:44 -03:00
}
// Push the Lua table onto the stack
L . Push ( luaTable )
}
// pushMapStringFloat64ToLua pushes a map of string-float64 pairs to a Lua table on the stack.
//
// L *lua.LState - the Lua state
// m map[string]float64 - the map to be pushed to Lua
func pushMapStringFloat64ToLua ( L * lua . LState , m map [ string ] float64 ) {
// Create a new Lua table
luaTable := L . NewTable ( )
// Iterate over the Go map and set the key-value pairs in the Lua table
for key , value := range m {
// Use lua.LNumber since Lua does not differentiate between float and int
2024-03-08 21:39:05 +01:00
L . SetTable ( luaTable , lua . LString ( key ) , lua . LNumber ( value ) )
2024-03-06 12:56:44 -03:00
}
// Push the Lua table onto the stack
L . Push ( luaTable )
}
2024-04-13 12:40:43 +02:00
func pushSliceNumericToLua [ T float64 | int | byte ] ( L * lua . LState , slice [ ] T ) {
// Create a new Lua table
luaTable := L . NewTable ( )
// Iterate over the Go slice and set the elements in the Lua table
2024-03-06 12:56:44 -03:00
for _ , value := range slice {
// Append the value to the Lua table
// Lua is 1-indexed, so we use the length of the table + 1 as the next index
luaTable . Append ( lua . LNumber ( value ) )
}
// Push the Lua table onto the stack
L . Push ( luaTable )
}
// pushSliceStringToLua creates a new Lua table and sets the elements in the table from the given Go slice. It then pushes the Lua table onto the stack.
//
// L *lua.LState - The Lua state
// slice []string - The Go slice of strings
func pushSliceStringToLua ( L * lua . LState , slice [ ] string ) {
// Create a new Lua table
luaTable := L . NewTable ( )
// Iterate over the Go slice and set the elements in the Lua table
for _ , value := range slice {
// Append the value to the Lua table
luaTable . Append ( lua . LString ( value ) )
}
// Push the Lua table onto the stack
L . Push ( luaTable )
}
// pushSliceBoolToLua creates a new Lua table and pushes the boolean values from the given slice onto the Lua stack.
//
// L *lua.LState - the Lua state
// slice []bool - the Go slice containing boolean values
func pushSliceBoolToLua ( L * lua . LState , slice [ ] bool ) {
// Create a new Lua table
luaTable := L . NewTable ( )
// Iterate over the Go slice and insert each boolean into the Lua table
for _ , value := range slice {
// Lua is 1-indexed, so we use the length of the table + 1 as the next index
luaTable . Append ( lua . LBool ( value ) )
}
// Push the Lua table onto the stack
L . Push ( luaTable )
}