From 9876b0ce8f3202bef7e22ae0e2cef75399829e0e Mon Sep 17 00:00:00 2001 From: Mike Farah Date: Mon, 21 Dec 2020 11:42:35 +1100 Subject: [PATCH] Boolean operators now use the crossFunction util func --- pkg/yqlib/oeprator_alternative_test.go | 7 +++ pkg/yqlib/operator_booleans.go | 75 +++++++------------------- 2 files changed, 27 insertions(+), 55 deletions(-) diff --git a/pkg/yqlib/oeprator_alternative_test.go b/pkg/yqlib/oeprator_alternative_test.go index a2661c71..bb4b3ca6 100644 --- a/pkg/yqlib/oeprator_alternative_test.go +++ b/pkg/yqlib/oeprator_alternative_test.go @@ -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) { diff --git a/pkg/yqlib/operator_booleans.go b/pkg/yqlib/operator_booleans.go index 74c32cea..575ac785 100644 --- a/pkg/yqlib/operator_booleans.go +++ b/pkg/yqlib/operator_booleans.go @@ -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) - if errDecoding != nil { - return errDecoding - } - boolResult := createBooleanCandidate(lhsCandidate, op(lhsTrue, rhsTrue)) - results.PushBack(boolResult) + rhsTrue, errDecoding := isTruthy(rhs) + if errDecoding != nil { + return nil, errDecoding } + + return createBooleanCandidate(lhs, op(lhsTrue, rhsTrue)), nil } - 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) - } - - 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 - } - 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 b1 || b2 - }) + 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 b1 && b2 - }) + 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) {