mirror of
				https://github.com/taigrr/yq
				synced 2025-01-18 04:53:17 -08: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) | ||||
| 			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) { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user