add type utilities
This commit is contained in:
parent
44337fffe3
commit
a2b4b1c927
101
types.go
101
types.go
|
@ -4,6 +4,10 @@ package luajit
|
||||||
#include <lua.h>
|
#include <lua.h>
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
// LuaType represents Lua value types
|
// LuaType represents Lua value types
|
||||||
type LuaType int
|
type LuaType int
|
||||||
|
@ -49,3 +53,100 @@ func (t LuaType) String() string {
|
||||||
return "unknown"
|
return "unknown"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ConvertValue converts a value to the requested type with proper type conversion
|
||||||
|
func ConvertValue[T any](value any) (T, bool) {
|
||||||
|
var zero T
|
||||||
|
|
||||||
|
// Handle nil case
|
||||||
|
if value == nil {
|
||||||
|
return zero, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try direct type assertion first
|
||||||
|
if result, ok := value.(T); ok {
|
||||||
|
return result, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type-specific conversions
|
||||||
|
switch any(zero).(type) {
|
||||||
|
case string:
|
||||||
|
switch v := value.(type) {
|
||||||
|
case float64:
|
||||||
|
return any(fmt.Sprintf("%g", v)).(T), true
|
||||||
|
case int:
|
||||||
|
return any(strconv.Itoa(v)).(T), true
|
||||||
|
case bool:
|
||||||
|
if v {
|
||||||
|
return any("true").(T), true
|
||||||
|
}
|
||||||
|
return any("false").(T), true
|
||||||
|
}
|
||||||
|
case int:
|
||||||
|
switch v := value.(type) {
|
||||||
|
case float64:
|
||||||
|
return any(int(v)).(T), true
|
||||||
|
case string:
|
||||||
|
if i, err := strconv.Atoi(v); err == nil {
|
||||||
|
return any(i).(T), true
|
||||||
|
}
|
||||||
|
case bool:
|
||||||
|
if v {
|
||||||
|
return any(1).(T), true
|
||||||
|
}
|
||||||
|
return any(0).(T), true
|
||||||
|
}
|
||||||
|
case float64:
|
||||||
|
switch v := value.(type) {
|
||||||
|
case int:
|
||||||
|
return any(float64(v)).(T), true
|
||||||
|
case string:
|
||||||
|
if f, err := strconv.ParseFloat(v, 64); err == nil {
|
||||||
|
return any(f).(T), true
|
||||||
|
}
|
||||||
|
case bool:
|
||||||
|
if v {
|
||||||
|
return any(1.0).(T), true
|
||||||
|
}
|
||||||
|
return any(0.0).(T), true
|
||||||
|
}
|
||||||
|
case bool:
|
||||||
|
switch v := value.(type) {
|
||||||
|
case string:
|
||||||
|
switch v {
|
||||||
|
case "true", "yes", "1":
|
||||||
|
return any(true).(T), true
|
||||||
|
case "false", "no", "0":
|
||||||
|
return any(false).(T), true
|
||||||
|
}
|
||||||
|
case int:
|
||||||
|
return any(v != 0).(T), true
|
||||||
|
case float64:
|
||||||
|
return any(v != 0).(T), true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return zero, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTypedValue gets a value from the state with type conversion
|
||||||
|
func GetTypedValue[T any](s *State, index int) (T, bool) {
|
||||||
|
var zero T
|
||||||
|
|
||||||
|
// Get the value as any type
|
||||||
|
value, err := s.ToValue(index)
|
||||||
|
if err != nil {
|
||||||
|
return zero, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert it to the requested type
|
||||||
|
return ConvertValue[T](value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetGlobalTyped gets a global variable with type conversion
|
||||||
|
func GetGlobalTyped[T any](s *State, name string) (T, bool) {
|
||||||
|
s.GetGlobal(name)
|
||||||
|
defer s.Pop(1)
|
||||||
|
|
||||||
|
return GetTypedValue[T](s, -1)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user