mirror of
https://github.com/mikefarah/yq.git
synced 2024-11-12 13:48:06 +00:00
Fixed boolean ops
This commit is contained in:
parent
bc87aca8d7
commit
f03005f86d
@ -6,7 +6,7 @@ Which will assign the LHS node values to the RHS node values. The RHS expression
|
|||||||
### relative form: `|=`
|
### relative form: `|=`
|
||||||
This will do a similar thing to the plain form, however, the RHS expression is run against _the LHS nodes_. This is useful for updating values based on old values, e.g. increment.
|
This will do a similar thing to the plain form, however, the RHS expression is run against _the LHS nodes_. This is useful for updating values based on old values, e.g. increment.
|
||||||
## Examples
|
## Examples
|
||||||
### Update parent to be the child value
|
### Update node to be the child value
|
||||||
Given a sample.yml file of:
|
Given a sample.yml file of:
|
||||||
```yaml
|
```yaml
|
||||||
a:
|
a:
|
||||||
@ -23,7 +23,7 @@ a:
|
|||||||
g: foof
|
g: foof
|
||||||
```
|
```
|
||||||
|
|
||||||
### Update to be the sibling value
|
### Update node to be the sibling value
|
||||||
Given a sample.yml file of:
|
Given a sample.yml file of:
|
||||||
```yaml
|
```yaml
|
||||||
a:
|
a:
|
||||||
|
@ -3,7 +3,7 @@ package yqlib
|
|||||||
import (
|
import (
|
||||||
"container/list"
|
"container/list"
|
||||||
|
|
||||||
"gopkg.in/yaml.v3"
|
yaml "gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
func isTruthy(c *CandidateNode) (bool, error) {
|
func isTruthy(c *CandidateNode) (bool, error) {
|
||||||
@ -25,9 +25,42 @@ func isTruthy(c *CandidateNode) (bool, error) {
|
|||||||
|
|
||||||
type boolOp func(bool, bool) bool
|
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)
|
||||||
|
if errDecoding != nil {
|
||||||
|
return 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func booleanOp(d *dataTreeNavigator, matchingNodes *list.List, pathNode *PathTreeNode, op boolOp) (*list.List, error) {
|
func booleanOp(d *dataTreeNavigator, matchingNodes *list.List, pathNode *PathTreeNode, op boolOp) (*list.List, error) {
|
||||||
var results = list.New()
|
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() {
|
for el := matchingNodes.Front(); el != nil; el = el.Next() {
|
||||||
candidate := el.Value.(*CandidateNode)
|
candidate := el.Value.(*CandidateNode)
|
||||||
lhs, err := d.GetMatchingNodes(nodeToMap(candidate), pathNode.Lhs)
|
lhs, err := d.GetMatchingNodes(nodeToMap(candidate), pathNode.Lhs)
|
||||||
@ -39,23 +72,9 @@ func booleanOp(d *dataTreeNavigator, matchingNodes *list.List, pathNode *PathTre
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for lhsChild := lhs.Front(); lhsChild != nil; lhsChild = lhsChild.Next() {
|
err = performBoolOp(results, lhs, rhs, op)
|
||||||
lhsCandidate := lhsChild.Value.(*CandidateNode)
|
if err != nil {
|
||||||
lhsTrue, errDecoding := isTruthy(lhsCandidate)
|
return nil, err
|
||||||
if errDecoding != nil {
|
|
||||||
return nil, errDecoding
|
|
||||||
}
|
|
||||||
|
|
||||||
for rhsChild := rhs.Front(); rhsChild != nil; rhsChild = rhsChild.Next() {
|
|
||||||
rhsCandidate := rhsChild.Value.(*CandidateNode)
|
|
||||||
rhsTrue, errDecoding := isTruthy(rhsCandidate)
|
|
||||||
if errDecoding != nil {
|
|
||||||
return nil, errDecoding
|
|
||||||
}
|
|
||||||
boolResult := createBooleanCandidate(lhsCandidate, op(lhsTrue, rhsTrue))
|
|
||||||
|
|
||||||
results.PushBack(boolResult)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -24,8 +24,8 @@ var booleanOperatorScenarios = []expressionScenario{
|
|||||||
description: "Matching nodes with select, equals and or",
|
description: "Matching nodes with select, equals and or",
|
||||||
expression: `.[] | select(.a == "cat" or .b == "dog")`,
|
expression: `.[] | select(.a == "cat" or .b == "dog")`,
|
||||||
expected: []string{
|
expected: []string{
|
||||||
"D0, P[], (!!map)::{a: bird, b: dog}\n",
|
"D0, P[0], (!!map)::{a: bird, b: dog}\n",
|
||||||
"D0, P[], (!!map)::{a: cat, b: fly}\n",
|
"D0, P[2], (!!map)::{a: cat, b: fly}\n",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user