mirror of
https://github.com/mikefarah/yq.git
synced 2024-12-19 20:19:04 +00:00
Move parseValue to yqlib/value_parser.go
This commit is contained in:
parent
64d1e58f97
commit
95fec2984e
@ -4,17 +4,17 @@ type PathParser interface {
|
|||||||
ParsePath(path string) []string
|
ParsePath(path string) []string
|
||||||
}
|
}
|
||||||
|
|
||||||
type parser struct{}
|
type pathParser struct{}
|
||||||
|
|
||||||
func NewPathParser() PathParser {
|
func NewPathParser() PathParser {
|
||||||
return &parser{}
|
return &pathParser{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) ParsePath(path string) []string {
|
func (p *pathParser) ParsePath(path string) []string {
|
||||||
return p.parsePathAccum([]string{}, path)
|
return p.parsePathAccum([]string{}, path)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) parsePathAccum(paths []string, remaining string) []string {
|
func (p *pathParser) parsePathAccum(paths []string, remaining string) []string {
|
||||||
head, tail := p.nextYamlPath(remaining)
|
head, tail := p.nextYamlPath(remaining)
|
||||||
if tail == "" {
|
if tail == "" {
|
||||||
return append(paths, head)
|
return append(paths, head)
|
||||||
@ -22,7 +22,7 @@ func (p *parser) parsePathAccum(paths []string, remaining string) []string {
|
|||||||
return p.parsePathAccum(append(paths, head), tail)
|
return p.parsePathAccum(append(paths, head), tail)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) nextYamlPath(path string) (pathElement string, remaining string) {
|
func (p *pathParser) nextYamlPath(path string) (pathElement string, remaining string) {
|
||||||
switch path[0] {
|
switch path[0] {
|
||||||
case '[':
|
case '[':
|
||||||
// e.g [0].blah.cat -> we need to return "0" and "blah.cat"
|
// e.g [0].blah.cat -> we need to return "0" and "blah.cat"
|
||||||
@ -36,7 +36,7 @@ func (p *parser) nextYamlPath(path string) (pathElement string, remaining string
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) search(path string, matchingChars []uint8, skipNext bool) (pathElement string, remaining string) {
|
func (p *pathParser) search(path string, matchingChars []uint8, skipNext bool) (pathElement string, remaining string) {
|
||||||
for i := 0; i < len(path); i++ {
|
for i := 0; i < len(path); i++ {
|
||||||
var char = path[i]
|
var char = path[i]
|
||||||
if p.contains(matchingChars, char) {
|
if p.contains(matchingChars, char) {
|
||||||
@ -55,7 +55,7 @@ func (p *parser) search(path string, matchingChars []uint8, skipNext bool) (path
|
|||||||
return path, ""
|
return path, ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) contains(matchingChars []uint8, candidate uint8) bool {
|
func (p *pathParser) contains(matchingChars []uint8, candidate uint8) bool {
|
||||||
for _, a := range matchingChars {
|
for _, a := range matchingChars {
|
||||||
if a == candidate {
|
if a == candidate {
|
||||||
return true
|
return true
|
||||||
|
35
pkg/yqlib/value_parser.go
Normal file
35
pkg/yqlib/value_parser.go
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package yqlib
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ValueParser interface {
|
||||||
|
ParseValue(argument string) interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type valueParser struct{}
|
||||||
|
|
||||||
|
func NewValueParser() ValueParser {
|
||||||
|
return &valueParser{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *valueParser) ParseValue(argument string) interface{} {
|
||||||
|
var value, err interface{}
|
||||||
|
var inQuotes = len(argument) > 0 && argument[0] == '"'
|
||||||
|
if !inQuotes {
|
||||||
|
value, err = strconv.ParseFloat(argument, 64)
|
||||||
|
if err == nil {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
value, err = strconv.ParseBool(argument)
|
||||||
|
if err == nil {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
if argument == "[]" {
|
||||||
|
return make([]interface{}, 0)
|
||||||
|
}
|
||||||
|
return argument
|
||||||
|
}
|
||||||
|
return argument[1 : len(argument)-1]
|
||||||
|
}
|
25
pkg/yqlib/value_parser_test.go
Normal file
25
pkg/yqlib/value_parser_test.go
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package yqlib
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/mikefarah/yq/test"
|
||||||
|
)
|
||||||
|
|
||||||
|
var parseValueTests = []struct {
|
||||||
|
argument string
|
||||||
|
expectedResult interface{}
|
||||||
|
testDescription string
|
||||||
|
}{
|
||||||
|
{"true", true, "boolean"},
|
||||||
|
{"\"true\"", "true", "boolean as string"},
|
||||||
|
{"3.4", 3.4, "number"},
|
||||||
|
{"\"3.4\"", "3.4", "number as string"},
|
||||||
|
{"", "", "empty string"},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseValue(t *testing.T) {
|
||||||
|
for _, tt := range parseValueTests {
|
||||||
|
test.AssertResultWithContext(t, tt.expectedResult, NewValueParser().ParseValue(tt.argument), tt.testDescription)
|
||||||
|
}
|
||||||
|
}
|
23
yq.go
23
yq.go
@ -34,6 +34,7 @@ var log = logging.MustGetLogger("yq")
|
|||||||
var lib = yqlib.NewYqLib(log)
|
var lib = yqlib.NewYqLib(log)
|
||||||
var jsonConverter = marshal.NewJsonConverter()
|
var jsonConverter = marshal.NewJsonConverter()
|
||||||
var yamlConverter = marshal.NewYamlConverter()
|
var yamlConverter = marshal.NewYamlConverter()
|
||||||
|
var valueParser = yqlib.NewValueParser()
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
cmd := newCommandCLI()
|
cmd := newCommandCLI()
|
||||||
@ -557,31 +558,11 @@ func readWriteCommands(args []string, expectedArgs int, badArgsMessage string) (
|
|||||||
return nil, errors.New(badArgsMessage)
|
return nil, errors.New(badArgsMessage)
|
||||||
} else {
|
} else {
|
||||||
writeCommands = make(yaml.MapSlice, 1)
|
writeCommands = make(yaml.MapSlice, 1)
|
||||||
writeCommands[0] = yaml.MapItem{Key: args[expectedArgs-2], Value: parseValue(args[expectedArgs-1])}
|
writeCommands[0] = yaml.MapItem{Key: args[expectedArgs-2], Value: valueParser.ParseValue(args[expectedArgs-1])}
|
||||||
}
|
}
|
||||||
return writeCommands, nil
|
return writeCommands, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseValue(argument string) interface{} {
|
|
||||||
var value, err interface{}
|
|
||||||
var inQuotes = len(argument) > 0 && argument[0] == '"'
|
|
||||||
if !inQuotes {
|
|
||||||
value, err = strconv.ParseFloat(argument, 64)
|
|
||||||
if err == nil {
|
|
||||||
return value
|
|
||||||
}
|
|
||||||
value, err = strconv.ParseBool(argument)
|
|
||||||
if err == nil {
|
|
||||||
return value
|
|
||||||
}
|
|
||||||
if argument == "[]" {
|
|
||||||
return make([]interface{}, 0)
|
|
||||||
}
|
|
||||||
return argument
|
|
||||||
}
|
|
||||||
return argument[1 : len(argument)-1]
|
|
||||||
}
|
|
||||||
|
|
||||||
func toString(context interface{}) (string, error) {
|
func toString(context interface{}) (string, error) {
|
||||||
if outputToJSON {
|
if outputToJSON {
|
||||||
return jsonConverter.JsonToString(context)
|
return jsonConverter.JsonToString(context)
|
||||||
|
18
yq_test.go
18
yq_test.go
@ -9,24 +9,6 @@ import (
|
|||||||
"github.com/mikefarah/yq/test"
|
"github.com/mikefarah/yq/test"
|
||||||
)
|
)
|
||||||
|
|
||||||
var parseValueTests = []struct {
|
|
||||||
argument string
|
|
||||||
expectedResult interface{}
|
|
||||||
testDescription string
|
|
||||||
}{
|
|
||||||
{"true", true, "boolean"},
|
|
||||||
{"\"true\"", "true", "boolean as string"},
|
|
||||||
{"3.4", 3.4, "number"},
|
|
||||||
{"\"3.4\"", "3.4", "number as string"},
|
|
||||||
{"", "", "empty string"},
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestParseValue(t *testing.T) {
|
|
||||||
for _, tt := range parseValueTests {
|
|
||||||
test.AssertResultWithContext(t, tt.expectedResult, parseValue(tt.argument), tt.testDescription)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMultilineString(t *testing.T) {
|
func TestMultilineString(t *testing.T) {
|
||||||
testString := `
|
testString := `
|
||||||
abcd
|
abcd
|
||||||
|
Loading…
Reference in New Issue
Block a user