yq/pkg/yqlib/operator_slice.go

69 lines
2.2 KiB
Go
Raw Normal View History

2022-10-29 07:15:21 +00:00
package yqlib
import (
"container/list"
2022-11-10 07:03:18 +00:00
"fmt"
2022-10-29 07:15:21 +00:00
)
2022-11-10 07:03:18 +00:00
func getSliceNumber(d *dataTreeNavigator, context Context, node *CandidateNode, expressionNode *ExpressionNode) (int, error) {
result, err := d.GetMatchingNodes(context.SingleChildContext(node), expressionNode)
if err != nil {
return 0, err
}
if result.MatchingNodes.Len() != 1 {
return 0, fmt.Errorf("expected to find 1 number, got %v instead", result.MatchingNodes.Len())
}
2023-04-11 02:39:22 +00:00
return parseInt(result.MatchingNodes.Front().Value.(*CandidateNode).Value)
2022-10-29 07:15:21 +00:00
}
func sliceArrayOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
2022-11-10 07:03:18 +00:00
log.Debug("slice array operator!")
log.Debug("lhs: %v", expressionNode.LHS.Operation.toString())
log.Debug("rhs: %v", expressionNode.RHS.Operation.toString())
2022-10-29 07:15:21 +00:00
results := list.New()
2022-11-10 07:03:18 +00:00
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
2023-04-11 02:39:22 +00:00
lhsNode := el.Value.(*CandidateNode).unwrapDocument()
2022-10-29 07:15:21 +00:00
2022-11-10 07:03:18 +00:00
firstNumber, err := getSliceNumber(d, context, lhsNode, expressionNode.LHS)
if err != nil {
return Context{}, err
}
2022-10-29 07:15:21 +00:00
relativeFirstNumber := firstNumber
if relativeFirstNumber < 0 {
2023-04-11 02:39:22 +00:00
relativeFirstNumber = len(lhsNode.Content) + firstNumber
2022-10-29 07:15:21 +00:00
}
2022-11-10 07:03:18 +00:00
secondNumber, err := getSliceNumber(d, context, lhsNode, expressionNode.RHS)
if err != nil {
return Context{}, err
}
relativeSecondNumber := secondNumber
if relativeSecondNumber < 0 {
2023-04-11 02:39:22 +00:00
relativeSecondNumber = len(lhsNode.Content) + secondNumber
} else if relativeSecondNumber > len(lhsNode.Content) {
relativeSecondNumber = len(lhsNode.Content)
2022-10-29 07:15:21 +00:00
}
log.Debug("calculateIndicesToTraverse: slice from %v to %v", relativeFirstNumber, relativeSecondNumber)
2023-04-11 02:39:22 +00:00
var newResults []*CandidateNode
2022-10-29 07:15:21 +00:00
for i := relativeFirstNumber; i < relativeSecondNumber; i++ {
2023-04-11 02:39:22 +00:00
newResults = append(newResults, lhsNode.Content[i])
2022-10-29 07:15:21 +00:00
}
2023-04-11 02:39:22 +00:00
sliceArrayNode := lhsNode.CreateReplacement(SequenceNode, lhsNode.Tag, "")
2023-05-09 03:51:21 +00:00
sliceArrayNode.AddChildren(newResults)
2023-04-11 02:39:22 +00:00
results.PushBack(sliceArrayNode)
2022-10-29 07:15:21 +00:00
}
// result is now the context that has the nodes we need to put back into a sequence.
//what about multiple arrays in the context? I think we need to create an array for each one
return context.ChildContext(results), nil
}