mirror of
https://github.com/mikefarah/yq.git
synced 2026-09-05 00:54:51 +08:00
binary tree ftw
This commit is contained in:
@@ -1,23 +1,73 @@
|
||||
package yqlib
|
||||
|
||||
// import yaml "gopkg.in/yaml.v3"
|
||||
type dataTreeNavigator struct {
|
||||
}
|
||||
|
||||
// type NodeLeafContext struct {
|
||||
// Node *yaml.Node
|
||||
// Head interface{}
|
||||
// PathStack []interface{}
|
||||
// }
|
||||
type DataTreeNavigator interface {
|
||||
GetMatchingNodes(matchingNodes []*NodeContext, pathNode *PathTreeNode) ([]*NodeContext, error)
|
||||
}
|
||||
|
||||
// func newNodeLeafContext(node *yaml.Node, head interface{}, tailpathStack []interface{}) NodeLeafContext {
|
||||
// newPathStack := make([]interface{}, len(pathStack))
|
||||
// copy(newPathStack, pathStack)
|
||||
// return NodeContext{
|
||||
// Node: node,
|
||||
// Head: head,
|
||||
// PathStack: newPathStack,
|
||||
// }
|
||||
// }
|
||||
func NewTreeNavigator() DataTreeNavigator {
|
||||
return &dataTreeNavigator{}
|
||||
}
|
||||
|
||||
// type DataTreeNavigator interface {
|
||||
// Traverse(value *NodeLeafContext)
|
||||
// }
|
||||
func (d *dataTreeNavigator) traverseSingle(matchingNode *NodeContext, pathNode *PathElement) ([]*NodeContext, error) {
|
||||
var value = matchingNode.Node
|
||||
// match all for splat
|
||||
// match all and recurse for deep
|
||||
// etc and so forth
|
||||
|
||||
}
|
||||
|
||||
func (d *dataTreeNavigator) traverse(matchingNodes []*NodeContext, pathNode *PathElement) ([]*NodeContext, error) {
|
||||
var newMatchingNodes = make([]*NodeContext, 0)
|
||||
var newNodes []*NodeContext
|
||||
var err error
|
||||
for _, node := range matchingNodes {
|
||||
|
||||
newNodes, err = d.traverseSingle(node, pathNode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
newMatchingNodes = append(newMatchingNodes, newNodes...)
|
||||
}
|
||||
|
||||
return newMatchingNodes, nil
|
||||
}
|
||||
|
||||
func (d *dataTreeNavigator) GetMatchingNodes(matchingNodes []*NodeContext, pathNode *PathTreeNode) ([]*NodeContext, error) {
|
||||
if pathNode.PathElement.PathElementType == PathKey || pathNode.PathElement.PathElementType == ArrayIndex {
|
||||
return d.traverse(matchingNodes, pathNode.PathElement)
|
||||
} else {
|
||||
var lhs, rhs []*NodeContext
|
||||
var err error
|
||||
switch pathNode.PathElement.OperationType {
|
||||
case Traverse:
|
||||
lhs, err = d.GetMatchingNodes(matchingNodes, pathNode.Lhs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return d.GetMatchingNodes(lhs, pathNode.Rhs)
|
||||
case Or, And:
|
||||
lhs, err = d.GetMatchingNodes(matchingNodes, pathNode.Lhs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rhs, err = d.GetMatchingNodes(matchingNodes, pathNode.Rhs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return d.setFunction(pathNode.PathElement, lhs, rhs), nil
|
||||
case Equals:
|
||||
lhs, err = d.GetMatchingNodes(matchingNodes, pathNode.Lhs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return d.findMatchingValues(lhs, pathNode.Rhs)
|
||||
case EqualsSelf:
|
||||
return d.findMatchingValues(matchingNodes, pathNode.Rhs)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user