github.com/dfcfw/lua@v0.0.0-20230325031207-0cc7ffb7b8b9/luar/metatable.go (about)

     1  package luar
     2  
     3  import (
     4  	"reflect"
     5  
     6  	"github.com/dfcfw/lua"
     7  )
     8  
     9  // Metatable is the Lua metatable for a Go type.
    10  type Metatable struct {
    11  	*lua.LTable
    12  }
    13  
    14  // MT returns the metatable for value's type. nil is returned if value's type
    15  // does not use a custom metatable.
    16  func MT(L *lua.LState, value interface{}) *Metatable {
    17  	if value == nil {
    18  		return nil
    19  	}
    20  
    21  	switch typ := reflect.TypeOf(value); typ.Kind() {
    22  	case reflect.Array, reflect.Chan, reflect.Map, reflect.Ptr, reflect.Slice, reflect.Struct:
    23  		return &Metatable{
    24  			LTable: getMetatable(L, typ),
    25  		}
    26  	}
    27  	return nil
    28  }
    29  
    30  func (m *Metatable) method(name string) lua.LValue {
    31  	methods := m.RawGetString("methods").(*lua.LTable)
    32  	if fn := methods.RawGetString(name); fn != lua.LNil {
    33  		return fn
    34  	}
    35  	return nil
    36  }
    37  
    38  func (m *Metatable) fieldIndex(name string) []int {
    39  	fields := m.RawGetString("fields").(*lua.LTable)
    40  	if index := fields.RawGetString(name); index != lua.LNil {
    41  		return index.(*lua.LUserData).Value.([]int)
    42  	}
    43  	return nil
    44  }