route/vendor/github.com/ailncode/gluaxmlpath/xmlpathtype.go

136 lines
2.8 KiB
Go

package gluaxmlpath
import (
"github.com/yuin/gopher-lua"
xmlpath "gopkg.in/xmlpath.v2"
)
type Node struct {
base *xmlpath.Node
}
type Path struct {
base *xmlpath.Path
}
type Iter struct {
base *xmlpath.Iter
}
const luaNodeTypeName = "xmlpath.node"
const luaPathTypeName = "xmlpath.path"
const luaIterTypeName = "xmlpath.iter"
func registerType(L *lua.LState, module *lua.LTable) {
//reg node
nodemt := L.NewTypeMetatable(luaNodeTypeName)
L.SetField(module, "node", nodemt)
L.SetField(nodemt, "__index", L.SetFuncs(L.NewTable(), map[string]lua.LGFunction{
"string": nodeString,
}))
//reg path
pathmt := L.NewTypeMetatable(luaPathTypeName)
L.SetField(module, "path", pathmt)
L.SetField(pathmt, "__index", L.SetFuncs(L.NewTable(), map[string]lua.LGFunction{
"iter": iter,
}))
//reg iter
itermt := L.NewTypeMetatable(luaIterTypeName)
L.SetField(module, "iter", itermt)
L.SetField(itermt, "__index", L.SetFuncs(L.NewTable(), map[string]lua.LGFunction{
//"next": next,
"node": node,
}))
}
func newNode(L *lua.LState, n *xmlpath.Node) *lua.LUserData {
ud := L.NewUserData()
ud.Value = &Node{
n,
}
L.SetMetatable(ud, L.GetTypeMetatable(luaNodeTypeName))
return ud
}
func checkNode(L *lua.LState) *Node {
ud := L.CheckUserData(1)
if v, ok := ud.Value.(*Node); ok {
return v
}
L.ArgError(1, "node expected")
return nil
}
func newPath(L *lua.LState, p *xmlpath.Path) *lua.LUserData {
ud := L.NewUserData()
ud.Value = &Path{
p,
}
L.SetMetatable(ud, L.GetTypeMetatable(luaPathTypeName))
return ud
}
func checkPath(L *lua.LState) *Path {
ud := L.CheckUserData(1)
if v, ok := ud.Value.(*Path); ok {
return v
}
L.ArgError(1, "path expected")
return nil
}
func newIter(L *lua.LState, i *xmlpath.Iter) *lua.LUserData {
ud := L.NewUserData()
ud.Value = &Iter{
i,
}
L.SetMetatable(ud, L.GetTypeMetatable(luaIterTypeName))
return ud
}
func checkIter(L *lua.LState) *Iter {
ud := L.CheckUserData(1)
if v, ok := ud.Value.(*Iter); ok {
return v
}
L.ArgError(1, "iter expected")
return nil
}
//iter := path.iter(node)
func iter(L *lua.LState) int {
path := checkPath(L)
if L.GetTop() == 2 {
ut := L.CheckUserData(2)
if node, ok := ut.Value.(*Node); ok {
it := path.base.Iter(node.base)
ltab := L.NewTable()
i := 1
for it.Next() {
L.RawSetInt(ltab, i, newNode(L, it.Node()))
i++
}
L.Push(ltab)
//L.Push(newIter(L, it))
return 1
}
}
L.ArgError(1, "node expected")
return 0
}
//support lua standard iterator
//hasNext := iter.next()
// func next(L *lua.LState) int {
// iter := checkIter(L)
// L.Push(lua.LBool(iter.base.Next()))
// return 1
// }
//node := iter.node()
func node(L *lua.LState) int {
iter := checkIter(L)
L.Push(newNode(L, iter.base.Node()))
return 1
}
//string := node.string()
func nodeString(L *lua.LState) int {
node := checkNode(L)
L.Push(lua.LString(node.base.String()))
return 1
}