mirror of
https://github.com/mikefarah/yq.git
synced 2024-11-12 13:48:06 +00:00
Boolean operators now use the crossFunction util func
This commit is contained in:
parent
a23272727d
commit
9876b0ce8f
@ -45,6 +45,13 @@ var alternativeOperatorScenarios = []expressionScenario{
|
||||
"D0, P[b], (!!str)::cat\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
skipDoc: true,
|
||||
expression: `false // true`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!bool)::true\n",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func TestAlternativeOperatorScenarios(t *testing.T) {
|
||||
|
@ -25,74 +25,39 @@ func isTruthy(c *CandidateNode) (bool, error) {
|
||||
|
||||
type boolOp func(bool, bool) bool
|
||||
|
||||
func performBoolOp(results *list.List, lhs *list.List, rhs *list.List, op boolOp) error {
|
||||
for lhsChild := lhs.Front(); lhsChild != nil; lhsChild = lhsChild.Next() {
|
||||
lhsCandidate := lhsChild.Value.(*CandidateNode)
|
||||
lhsTrue, errDecoding := isTruthy(lhsCandidate)
|
||||
func performBoolOp(op boolOp) func(d *dataTreeNavigator, lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) {
|
||||
return func(d *dataTreeNavigator, lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) {
|
||||
lhs.Node = UnwrapDoc(lhs.Node)
|
||||
rhs.Node = UnwrapDoc(rhs.Node)
|
||||
|
||||
lhsTrue, errDecoding := isTruthy(lhs)
|
||||
if errDecoding != nil {
|
||||
return errDecoding
|
||||
return nil, errDecoding
|
||||
}
|
||||
|
||||
for rhsChild := rhs.Front(); rhsChild != nil; rhsChild = rhsChild.Next() {
|
||||
rhsCandidate := rhsChild.Value.(*CandidateNode)
|
||||
rhsTrue, errDecoding := isTruthy(rhsCandidate)
|
||||
rhsTrue, errDecoding := isTruthy(rhs)
|
||||
if errDecoding != nil {
|
||||
return errDecoding
|
||||
}
|
||||
boolResult := createBooleanCandidate(lhsCandidate, op(lhsTrue, rhsTrue))
|
||||
results.PushBack(boolResult)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func booleanOp(d *dataTreeNavigator, matchingNodes *list.List, pathNode *PathTreeNode, op boolOp) (*list.List, error) {
|
||||
var results = list.New()
|
||||
|
||||
if matchingNodes.Len() == 0 {
|
||||
lhs, err := d.GetMatchingNodes(list.New(), pathNode.Lhs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rhs, err := d.GetMatchingNodes(list.New(), pathNode.Rhs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return results, performBoolOp(results, lhs, rhs, op)
|
||||
return nil, errDecoding
|
||||
}
|
||||
|
||||
for el := matchingNodes.Front(); el != nil; el = el.Next() {
|
||||
candidate := el.Value.(*CandidateNode)
|
||||
lhs, err := d.GetMatchingNodes(nodeToMap(candidate), pathNode.Lhs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return createBooleanCandidate(lhs, op(lhsTrue, rhsTrue)), nil
|
||||
}
|
||||
rhs, err := d.GetMatchingNodes(nodeToMap(candidate), pathNode.Rhs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = performBoolOp(results, lhs, rhs, op)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
}
|
||||
return results, nil
|
||||
}
|
||||
|
||||
func OrOperator(d *dataTreeNavigator, matchingNodes *list.List, pathNode *PathTreeNode) (*list.List, error) {
|
||||
log.Debugf("-- orOp")
|
||||
return booleanOp(d, matchingNodes, pathNode, func(b1 bool, b2 bool) bool {
|
||||
return crossFunction(d, matchingNodes, pathNode, performBoolOp(
|
||||
func(b1 bool, b2 bool) bool {
|
||||
return b1 || b2
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
func AndOperator(d *dataTreeNavigator, matchingNodes *list.List, pathNode *PathTreeNode) (*list.List, error) {
|
||||
log.Debugf("-- AndOp")
|
||||
return booleanOp(d, matchingNodes, pathNode, func(b1 bool, b2 bool) bool {
|
||||
return crossFunction(d, matchingNodes, pathNode, performBoolOp(
|
||||
func(b1 bool, b2 bool) bool {
|
||||
return b1 && b2
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
func NotOperator(d *dataTreeNavigator, matchMap *list.List, pathNode *PathTreeNode) (*list.List, error) {
|
||||
|
Loading…
Reference in New Issue
Block a user