1
1
mirror of https://github.com/wader/fq.git synced 2024-11-25 23:13:19 +03:00

Merge pull request #340 from wader/gojq-update-to-value-order

gojq: Preserve keys order for to_entries when used with JQValue
This commit is contained in:
Mattias Wadman 2022-07-26 16:05:47 +02:00 committed by GitHub
commit 9e34754fca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 89 additions and 73 deletions

2
go.mod
View File

@ -4,7 +4,7 @@ go 1.18
require (
// fork of github.com/itchyny/gojq, see github.com/wader/gojq fq branch
github.com/wader/gojq v0.12.1-0.20220703094036-0eed2734a1d7
github.com/wader/gojq v0.12.1-0.20220726134752-5daae754d327
// fork of github.com/chzyer/readline, see github.com/wader/readline fq branch
github.com/wader/readline v0.0.0-20220704090837-31be50517a56
)

4
go.sum
View File

@ -21,8 +21,8 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWb
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/wader/gojq v0.12.1-0.20220703094036-0eed2734a1d7 h1:3IQ6iYU/tkMcEpYu64CfhzQZNemPevlQyOsiga5uN2o=
github.com/wader/gojq v0.12.1-0.20220703094036-0eed2734a1d7/go.mod h1:HM2cB+ANeJ4kBhxQp/4cNKewKjvYHACuCpBneQBgHkg=
github.com/wader/gojq v0.12.1-0.20220726134752-5daae754d327 h1:HajMOMaPJWLIWdDGLIeOhNPIY8AZEe3ANiswa4/jRsI=
github.com/wader/gojq v0.12.1-0.20220726134752-5daae754d327/go.mod h1:HM2cB+ANeJ4kBhxQp/4cNKewKjvYHACuCpBneQBgHkg=
github.com/wader/readline v0.0.0-20220704090837-31be50517a56 h1:MEvdJFQfJD9D5nH2C5aXW+jWGcU1YmL8fJWIDsXvrJw=
github.com/wader/readline v0.0.0-20220704090837-31be50517a56/go.mod h1:Zgz8IJWvJoe7NK23CCPpC109XMCqJCpUhpHcnnA4XaM=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=

View File

@ -242,7 +242,7 @@ func (v Array) JQValueIndex(index int) any {
}
func (v Array) JQValueSlice(start int, end int) any { return v[start:end] }
func (v Array) JQValueKey(name string) any {
return ExpectedObjectError{Typ: "array"}
return ExpectedObjectError{Typ: gojq.JQTypeArray}
}
func (v Array) JQValueEach() any {
vs := make([]gojq.PathValue, len(v))
@ -261,16 +261,16 @@ func (v Array) JQValueKeys() any {
func (v Array) JQValueHas(key any) any {
intKey, ok := key.(int)
if !ok {
return HasKeyTypeError{L: "array", R: fmt.Sprintf("%v", key)}
return HasKeyTypeError{L: gojq.JQTypeArray, R: fmt.Sprintf("%v", key)}
}
return intKey >= 0 && intKey < len(v)
}
func (v Array) JQValueType() string { return "array" }
func (v Array) JQValueType() string { return gojq.JQTypeArray }
func (v Array) JQValueToNumber() any {
return FuncTypeNameError{Name: "tonumber", Typ: "array"}
return FuncTypeNameError{Name: "tonumber", Typ: gojq.JQTypeArray}
}
func (v Array) JQValueToString() any {
return FuncTypeNameError{Name: "tostring", Typ: "array"}
return FuncTypeNameError{Name: "tostring", Typ: gojq.JQTypeArray}
}
func (v Array) JQValueToGoJQ() any { return []any(v) }
@ -281,10 +281,10 @@ var _ gojq.JQValue = Object{}
type Object map[string]any
func (v Object) JQValueLength() any { return len(v) }
func (v Object) JQValueSliceLen() any { return ExpectedArrayError{Typ: "object"} }
func (v Object) JQValueIndex(index int) any { return ExpectedArrayError{Typ: "object"} }
func (v Object) JQValueSliceLen() any { return ExpectedArrayError{Typ: gojq.JQTypeObject} }
func (v Object) JQValueIndex(index int) any { return ExpectedArrayError{Typ: gojq.JQTypeObject} }
func (v Object) JQValueSlice(start int, end int) any {
return ExpectedArrayError{Typ: "object"}
return ExpectedArrayError{Typ: gojq.JQTypeObject}
}
func (v Object) JQValueKey(name string) any { return v[name] }
func (v Object) JQValueEach() any {
@ -308,17 +308,17 @@ func (v Object) JQValueKeys() any {
func (v Object) JQValueHas(key any) any {
stringKey, ok := key.(string)
if !ok {
return HasKeyTypeError{L: "object", R: fmt.Sprintf("%v", key)}
return HasKeyTypeError{L: gojq.JQTypeObject, R: fmt.Sprintf("%v", key)}
}
_, ok = v[stringKey]
return ok
}
func (v Object) JQValueType() string { return "object" }
func (v Object) JQValueType() string { return gojq.JQTypeObject }
func (v Object) JQValueToNumber() any {
return FuncTypeNameError{Name: "tonumber", Typ: "object"}
return FuncTypeNameError{Name: "tonumber", Typ: gojq.JQTypeObject}
}
func (v Object) JQValueToString() any {
return FuncTypeNameError{Name: "tostring", Typ: "object"}
return FuncTypeNameError{Name: "tostring", Typ: gojq.JQTypeObject}
}
func (v Object) JQValueToGoJQ() any { return map[string]any(v) }
@ -331,18 +331,18 @@ type Number struct {
}
func (v Number) JQValueLength() any { return v.V }
func (v Number) JQValueSliceLen() any { return ExpectedArrayError{Typ: "number"} }
func (v Number) JQValueIndex(index int) any { return ExpectedArrayError{Typ: "number"} }
func (v Number) JQValueSliceLen() any { return ExpectedArrayError{Typ: gojq.JQTypeNumber} }
func (v Number) JQValueIndex(index int) any { return ExpectedArrayError{Typ: gojq.JQTypeNumber} }
func (v Number) JQValueSlice(start int, end int) any {
return ExpectedArrayError{Typ: "number"}
return ExpectedArrayError{Typ: gojq.JQTypeNumber}
}
func (v Number) JQValueKey(name string) any { return ExpectedObjectError{Typ: "number"} }
func (v Number) JQValueEach() any { return IteratorError{Typ: "number"} }
func (v Number) JQValueKeys() any { return FuncTypeNameError{Name: "keys", Typ: "number"} }
func (v Number) JQValueKey(name string) any { return ExpectedObjectError{Typ: gojq.JQTypeNumber} }
func (v Number) JQValueEach() any { return IteratorError{Typ: gojq.JQTypeNumber} }
func (v Number) JQValueKeys() any { return FuncTypeNameError{Name: "keys", Typ: gojq.JQTypeNumber} }
func (v Number) JQValueHas(key any) any {
return FuncTypeNameError{Name: "has", Typ: "number"}
return FuncTypeNameError{Name: "has", Typ: gojq.JQTypeNumber}
}
func (v Number) JQValueType() string { return "number" }
func (v Number) JQValueType() string { return gojq.JQTypeNumber }
func (v Number) JQValueToNumber() any { return v.V }
func (v Number) JQValueToString() any {
b := &bytes.Buffer{}
@ -370,13 +370,13 @@ func (v String) JQValueIndex(index int) any {
return fmt.Sprintf("%c", v[index])
}
func (v String) JQValueSlice(start int, end int) any { return string(v[start:end]) }
func (v String) JQValueKey(name string) any { return ExpectedObjectError{Typ: "string"} }
func (v String) JQValueEach() any { return IteratorError{Typ: "string"} }
func (v String) JQValueKeys() any { return FuncTypeNameError{Name: "keys", Typ: "string"} }
func (v String) JQValueKey(name string) any { return ExpectedObjectError{Typ: gojq.JQTypeString} }
func (v String) JQValueEach() any { return IteratorError{Typ: gojq.JQTypeString} }
func (v String) JQValueKeys() any { return FuncTypeNameError{Name: "keys", Typ: gojq.JQTypeString} }
func (v String) JQValueHas(key any) any {
return FuncTypeNameError{Name: "has", Typ: "string"}
return FuncTypeNameError{Name: "has", Typ: gojq.JQTypeString}
}
func (v String) JQValueType() string { return "string" }
func (v String) JQValueType() string { return gojq.JQTypeString }
func (v String) JQValueToNumber() any {
if !gojq.ValidNumber(string(v)) {
return fmt.Errorf("invalid number: %q", string(v))
@ -393,22 +393,22 @@ var _ gojq.JQValue = Boolean(true)
type Boolean bool
func (v Boolean) JQValueLength() any {
return FuncTypeNameError{Name: "length", Typ: "boolean"}
return FuncTypeNameError{Name: "length", Typ: gojq.JQTypeBoolean}
}
func (v Boolean) JQValueSliceLen() any { return ExpectedArrayError{Typ: "boolean"} }
func (v Boolean) JQValueIndex(index int) any { return ExpectedArrayError{Typ: "boolean"} }
func (v Boolean) JQValueSliceLen() any { return ExpectedArrayError{Typ: gojq.JQTypeBoolean} }
func (v Boolean) JQValueIndex(index int) any { return ExpectedArrayError{Typ: gojq.JQTypeBoolean} }
func (v Boolean) JQValueSlice(start int, end int) any {
return ExpectedArrayError{Typ: "boolean"}
return ExpectedArrayError{Typ: gojq.JQTypeBoolean}
}
func (v Boolean) JQValueKey(name string) any { return ExpectedObjectError{Typ: "boolean"} }
func (v Boolean) JQValueEach() any { return IteratorError{Typ: "boolean"} }
func (v Boolean) JQValueKeys() any { return FuncTypeNameError{Name: "keys", Typ: "boolean"} }
func (v Boolean) JQValueKey(name string) any { return ExpectedObjectError{Typ: gojq.JQTypeBoolean} }
func (v Boolean) JQValueEach() any { return IteratorError{Typ: gojq.JQTypeBoolean} }
func (v Boolean) JQValueKeys() any { return FuncTypeNameError{Name: "keys", Typ: gojq.JQTypeBoolean} }
func (v Boolean) JQValueHas(key any) any {
return FuncTypeNameError{Name: "has", Typ: "boolean"}
return FuncTypeNameError{Name: "has", Typ: gojq.JQTypeBoolean}
}
func (v Boolean) JQValueType() string { return "boolean" }
func (v Boolean) JQValueType() string { return gojq.JQTypeBoolean }
func (v Boolean) JQValueToNumber() any {
return FuncTypeNameError{Name: "tonumber", Typ: "boolean"}
return FuncTypeNameError{Name: "tonumber", Typ: gojq.JQTypeBoolean}
}
func (v Boolean) JQValueToString() any {
if v {
@ -425,19 +425,19 @@ var _ gojq.JQValue = Null{}
type Null struct{}
func (v Null) JQValueLength() any { return 0 }
func (v Null) JQValueSliceLen() any { return ExpectedArrayError{Typ: "null"} }
func (v Null) JQValueIndex(index int) any { return ExpectedArrayError{Typ: "null"} }
func (v Null) JQValueSlice(start int, end int) any { return ExpectedArrayError{Typ: "null"} }
func (v Null) JQValueKey(name string) any { return ExpectedObjectError{Typ: "null"} }
func (v Null) JQValueSliceLen() any { return ExpectedArrayError{Typ: gojq.JQTypeNull} }
func (v Null) JQValueIndex(index int) any { return ExpectedArrayError{Typ: gojq.JQTypeNull} }
func (v Null) JQValueSlice(start int, end int) any { return ExpectedArrayError{Typ: gojq.JQTypeNull} }
func (v Null) JQValueKey(name string) any { return ExpectedObjectError{Typ: gojq.JQTypeNull} }
func (v Null) JQValueEach() any { return IteratorError{Typ: "null"} }
func (v Null) JQValueKeys() any { return FuncTypeNameError{Name: "keys", Typ: "null"} }
func (v Null) JQValueEach() any { return IteratorError{Typ: gojq.JQTypeNull} }
func (v Null) JQValueKeys() any { return FuncTypeNameError{Name: "keys", Typ: gojq.JQTypeNull} }
func (v Null) JQValueHas(key any) any {
return FuncTypeNameError{Name: "has", Typ: "null"}
return FuncTypeNameError{Name: "has", Typ: gojq.JQTypeNull}
}
func (v Null) JQValueType() string { return "null" }
func (v Null) JQValueToNumber() any { return FuncTypeNameError{Name: "tonumber", Typ: "null"} }
func (v Null) JQValueToString() any { return "null" }
func (v Null) JQValueType() string { return gojq.JQTypeNull }
func (v Null) JQValueToNumber() any { return FuncTypeNameError{Name: "tonumber", Typ: gojq.JQTypeNull} }
func (v Null) JQValueToString() any { return gojq.JQTypeNull }
func (v Null) JQValueToGoJQ() any { return nil }
// Base
@ -460,7 +460,7 @@ func (v Base) JQValueKey(name string) any {
func (v Base) JQValueEach() any { return IteratorError{Typ: v.Typ} }
func (v Base) JQValueKeys() any { return FuncTypeNameError{Name: "keys", Typ: v.Typ} }
func (v Base) JQValueHas(key any) any {
return HasKeyTypeError{L: "array", R: fmt.Sprintf("%v", key)}
return HasKeyTypeError{L: gojq.JQTypeArray, R: fmt.Sprintf("%v", key)}
}
func (v Base) JQValueType() string { return v.Typ }
func (v Base) JQValueToNumber() any { return FuncTypeNameError{Name: "tonumber", Typ: v.Typ} }
@ -523,7 +523,7 @@ func (v *Lazy) JQValueEach() any {
}
func (v *Lazy) JQValueKeys() any {
if v.IsScalar {
return FuncTypeNameError{Name: "keys", Typ: "string"}
return FuncTypeNameError{Name: "keys", Typ: gojq.JQTypeString}
}
return v.f(func(jv gojq.JQValue) any { return jv.JQValueKeys() })
}

View File

@ -17,6 +17,7 @@ import (
"github.com/wader/fq/internal/progressreadseeker"
"github.com/wader/fq/pkg/bitio"
"github.com/wader/fq/pkg/ranges"
"github.com/wader/gojq"
)
func init() {
@ -366,13 +367,13 @@ func (b Binary) JQValueEach() any {
return nil
}
func (b Binary) JQValueType() string {
return "binary"
return gojq.JQTypeString
}
func (b Binary) JQValueKeys() any {
return gojqextra.FuncTypeNameError{Name: "keys", Typ: "binary"}
return gojqextra.FuncTypeNameError{Name: "keys", Typ: gojq.JQTypeString}
}
func (b Binary) JQValueHas(key any) any {
return gojqextra.HasKeyTypeError{L: "binary", R: fmt.Sprintf("%v", key)}
return gojqextra.HasKeyTypeError{L: gojq.JQTypeString, R: fmt.Sprintf("%v", key)}
}
func (b Binary) JQValueToNumber() any {
buf, err := b.toBytesBuffer(b.r)

View File

@ -654,7 +654,7 @@ type ArrayDecodeValue struct {
func NewArrayDecodeValue(dv *decode.Value, out any, c *decode.Compound) ArrayDecodeValue {
return ArrayDecodeValue{
decodeValueBase: decodeValueBase{dv: dv, out: out},
Base: gojqextra.Base{Typ: "array"},
Base: gojqextra.Base{Typ: gojq.JQTypeArray},
Compound: c,
}
}
@ -699,7 +699,7 @@ func (v ArrayDecodeValue) JQValueHas(key any) any {
func(key any) any {
intKey, ok := key.(int)
if !ok {
return gojqextra.HasKeyTypeError{L: "array", R: fmt.Sprintf("%v", key)}
return gojqextra.HasKeyTypeError{L: gojq.JQTypeArray, R: fmt.Sprintf("%v", key)}
}
return intKey >= 0 && intKey < len(v.Compound.Children)
})
@ -725,7 +725,7 @@ type StructDecodeValue struct {
func NewStructDecodeValue(dv *decode.Value, out any, c *decode.Compound) StructDecodeValue {
return StructDecodeValue{
decodeValueBase: decodeValueBase{dv: dv, out: out},
Base: gojqextra.Base{Typ: "object"},
Base: gojqextra.Base{Typ: gojq.JQTypeObject},
Compound: c,
}
}
@ -765,7 +765,7 @@ func (v StructDecodeValue) JQValueHas(key any) any {
func(key any) any {
stringKey, ok := key.(string)
if !ok {
return gojqextra.HasKeyTypeError{L: "object", R: fmt.Sprintf("%v", key)}
return gojqextra.HasKeyTypeError{L: gojq.JQTypeObject, R: fmt.Sprintf("%v", key)}
}
for _, f := range v.Compound.Children {
if f.Name == stringKey {

View File

@ -237,3 +237,18 @@ $ fq -d mp3 '[.frames[0] | ., .header] | add | keys, .bitrate' test.mp3
]
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x20| 40| @|.frames[0].header.bitrate: 56000 (4)
# make sure to_entries preserve struct order
$ fq -d mp3 '.frames[0] | keys' test.mp3
[
"header",
"side_info",
"xing",
"padding",
"crc_calculated"
]
$ fq -d mp3 '.frames[0] | to_entries[].key' test.mp3
"header"
"side_info"
"xing"
"padding"
"crc_calculated"

View File

@ -166,14 +166,14 @@ mp3> .headers._bits | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x00|49 44 33 04 00 00 00 00 00 23 54 53 53 45 00 00|ID3......#TSSE..|.: raw bits 0x0-0x2c.7 (45)
* |until 0x2c.7 (45) | |
"binary"
"string"
360
mp3>
mp3> .headers._bytes | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x00|49 44 33 04 00 00 00 00 00 23 54 53 53 45 00 00|ID3......#TSSE..|.: raw bits 0x0-0x2c.7 (45)
* |until 0x2c.7 (45) | |
"binary"
"string"
45
mp3>
mp3> .headers._error | ., type, length?

View File

@ -72,13 +72,13 @@ mp3> .headers[0].flags.unsynchronisation._path | ., type, length?
mp3> .headers[0].flags.unsynchronisation._bits | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0| 00 | . |.: raw bits 0x5-0x5 (0.1)
"binary"
"string"
1
mp3>
mp3> .headers[0].flags.unsynchronisation._bytes | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0| 00 | . |.: raw bits 0x5-0x5 (0.1)
"binary"
"string"
0
mp3>
mp3> .headers[0].flags.unsynchronisation._error | ., type, length?

View File

@ -80,13 +80,13 @@ json> (.)._path | ., type, length?
json> (.)._bits | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0|5b 5d| |[]| |.: raw bits 0x0-0x1.7 (2)
"binary"
"string"
16
json>
json> (.)._bytes | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0|5b 5d| |[]| |.: raw bits 0x0-0x1.7 (2)
"binary"
"string"
2
json>
json> (.)._error | ., type, length?

View File

@ -70,13 +70,13 @@ json> (.)._path | ., type, length?
json> (.)._bits | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0|7b 7d| |{}| |.: raw bits 0x0-0x1.7 (2)
"binary"
"string"
16
json>
json> (.)._bytes | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0|7b 7d| |{}| |.: raw bits 0x0-0x1.7 (2)
"binary"
"string"
2
json>
json> (.)._error | ., type, length?

View File

@ -84,13 +84,13 @@ mp3> .headers[0].padding._path | ., type, length?
mp3> .headers[0].padding._bits | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x20| 00 00 00 00 00 00 00 00 00 00 | .......... |.: raw bits 0x23-0x2c.7 (10)
"binary"
"string"
80
mp3>
mp3> .headers[0].padding._bytes | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x20| 00 00 00 00 00 00 00 00 00 00 | .......... |.: raw bits 0x23-0x2c.7 (10)
"binary"
"string"
10
mp3>
mp3> .headers[0].padding._error | ., type, length?

View File

@ -72,13 +72,13 @@ mp3> .headers[0].version._path | ., type, length?
mp3> .headers[0].version._bits | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0| 04 | . |.: raw bits 0x3-0x3.7 (1)
"binary"
"string"
8
mp3>
mp3> .headers[0].version._bytes | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0| 04 | . |.: raw bits 0x3-0x3.7 (1)
"binary"
"string"
1
mp3>
mp3> .headers[0].version._error | ., type, length?

View File

@ -88,13 +88,13 @@ mp3> .headers[0].flags._path | ., type, length?
mp3> .headers[0].flags._bits | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0| 00 | . |.: raw bits 0x5-0x5.7 (1)
"binary"
"string"
8
mp3>
mp3> .headers[0].flags._bytes | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0| 00 | . |.: raw bits 0x5-0x5.7 (1)
"binary"
"string"
1
mp3>
mp3> .headers[0].flags._error | ., type, length?

View File

@ -84,13 +84,13 @@ mp3> .headers[0].magic._path | ., type, length?
mp3> .headers[0].magic._bits | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0|49 44 33 |ID3 |.: raw bits 0x0-0x2.7 (3)
"binary"
"string"
24
mp3>
mp3> .headers[0].magic._bytes | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0|49 44 33 |ID3 |.: raw bits 0x0-0x2.7 (3)
"binary"
"string"
3
mp3>
mp3> .headers[0].magic._error | ., type, length?