2023-10-05 04:13:46 +00:00
|
|
|
package yqlib
|
|
|
|
|
|
|
|
import (
|
|
|
|
"container/list"
|
|
|
|
"fmt"
|
|
|
|
"strconv"
|
|
|
|
)
|
|
|
|
|
|
|
|
func tryConvertToNumber(value string) (string, bool) {
|
|
|
|
// try a int first
|
|
|
|
_, _, err := parseInt64(value)
|
|
|
|
if err == nil {
|
|
|
|
return "!!int", true
|
|
|
|
}
|
|
|
|
// try float
|
|
|
|
_, floatErr := strconv.ParseFloat(value, 64)
|
|
|
|
|
|
|
|
if floatErr == nil {
|
|
|
|
return "!!float", true
|
|
|
|
}
|
|
|
|
return "", false
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func toNumberOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
|
|
|
|
log.Debugf("ToNumberOperator")
|
|
|
|
|
|
|
|
var results = list.New()
|
|
|
|
|
|
|
|
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
|
|
|
|
candidate := el.Value.(*CandidateNode)
|
2023-10-18 01:11:53 +00:00
|
|
|
if candidate.Kind != ScalarNode {
|
|
|
|
return Context{}, fmt.Errorf("cannot convert node at path %v of tag %v to number", candidate.GetNicePath(), candidate.Tag)
|
2023-10-05 04:13:46 +00:00
|
|
|
}
|
|
|
|
|
2023-10-18 01:11:53 +00:00
|
|
|
if candidate.Tag == "!!int" || candidate.Tag == "!!float" {
|
2023-10-05 04:13:46 +00:00
|
|
|
// it already is a number!
|
|
|
|
results.PushBack(candidate)
|
|
|
|
} else {
|
2023-10-18 01:11:53 +00:00
|
|
|
tag, converted := tryConvertToNumber(candidate.Value)
|
2023-10-05 04:13:46 +00:00
|
|
|
if converted {
|
2023-10-18 01:11:53 +00:00
|
|
|
result := candidate.CreateReplacement(ScalarNode, tag, candidate.Value)
|
2023-10-05 04:13:46 +00:00
|
|
|
results.PushBack(result)
|
|
|
|
} else {
|
2023-10-18 01:11:53 +00:00
|
|
|
return Context{}, fmt.Errorf("cannot convert node value [%v] at path %v of tag %v to number", candidate.Value, candidate.GetNicePath(), candidate.Tag)
|
2023-10-05 04:13:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return context.ChildContext(results), nil
|
|
|
|
}
|