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>
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// LuaType represents Lua value types
|
||||
type LuaType int
|
||||
|
@ -49,3 +53,100 @@ func (t LuaType) String() string {
|
|||
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