You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
helm/pkg/events/lua/luamatic.go

108 lines
2.7 KiB

/*
Copyright 2018 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package lua
/*
import (
"reflect"
"github.com/yuin/gopher-lua"
)
// LuaTagName is the tag to be parsed as a Lua annotation
// This is mutable for nefarious purposes.
var LuaTagName = "lua"
var ErrUnsupportedKind = errors.New("unsupported kind")
func luamatic(name string, v interface{}, vm *lua.Lstate) error {
val := reflect.Indirect(reflect.ValueOf(v))
switch val.Kind() {
// TODO: are reflect.Interface, reflect.Ptr, and reflect.Uintptr okay?
// TODO: can Complex64/128 be represented by Lua
// TODO: is there any processing we need to do on maps, slices, and arrays?
case reflect.UnsafePointer, reflect.Chan, reflect.Invalid:
return ErrUnsupportedKind
case reflect.Struct:
// In this case, we create a UserData with associated metatable
mt := vm.NewTypeMetatable(name)
// Next we have to walk the struct and find the fields to add.
t := val.Type()
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
tag := gettag(&f)
iface := val.Field(i).Interface()
if tag.omit {
continue
}
// Now we have a struct tag on a field, and should make it accessible
// to Lua. Set value to Nil at this point
}
mt.SetField(mt, tag.name, lua.LNil)
vm.SetGlobal(name, mt)
ud := vm.NewUserData()
ud.Value = v
ud.SetMetatable(ud, vm.GetTypeMetatable(name))
vm.Push(ud)
return nil
default:
obj.Set(n, v)
for _, a := range aliases {
obj.Set(a, v)
}
return nil
}
}
func gettag(field *reflect.StructField) luaTag {
t := field.Tag.Get(LuaTagName)
if len(t) == 0 {
return luaTag{name: field.Name}
}
// We preserve the convention used by JSON, YAML, and other tags so that
// an evil library user can change LuaTagName to something and get rational
// output from this.
data := strings.Split(t, ",")
n := data[0]
if n == "-" {
return luaTag{name: field.Name, omit: true}
}
ot := luaTag{name: n}
if len(data) == 1 {
return ot
}
for _, k := range data[1:] {
switch item := k; {
case strings.HasPrefix(item, "alias="):
ot.aliases = append(ot.aliases, strings.TrimPrefix(item, "alias="))
}
}
return ot
}
type luaTag struct {
name string
omit bool
aliases []string
}
*/