1
1
mirror of https://github.com/wader/fq.git synced 2024-12-23 13:22:58 +03:00

gojq: Initial update support

decode value give no updateable error
JQValue json value tries to replicate behaveior
This commit is contained in:
Mattias Wadman 2021-08-15 14:07:16 +02:00
parent c3b7b5cad2
commit 0c7fa090b0
17 changed files with 703 additions and 425 deletions

2
go.mod
View File

@ -13,4 +13,4 @@ require (
replace github.com/chzyer/readline => github.com/wader/readline v0.0.0-20210708114437-6e459499aaf5
replace github.com/itchyny/gojq => github.com/wader/gojq v0.12.1-0.20210815085601-b5d8be28faea
replace github.com/itchyny/gojq => github.com/wader/gojq v0.12.1-0.20210815133234-fa23c60d2da1

4
go.sum
View File

@ -13,8 +13,8 @@ github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354/go.mod h1:KSVJ
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/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/wader/gojq v0.12.1-0.20210815085601-b5d8be28faea h1:n8MU47bCqWL/+U9MxhbMRUWe97txWtIAPsbyMMQrqfw=
github.com/wader/gojq v0.12.1-0.20210815085601-b5d8be28faea/go.mod h1:EQUSKgW/YaOxmXpAwGiowFDO4i2Rmtk5+9dFyeiymAg=
github.com/wader/gojq v0.12.1-0.20210815133234-fa23c60d2da1 h1:E51FeNldHd4SPpeBGuyu+LC0u/X/cagviC9Hk8eRY/o=
github.com/wader/gojq v0.12.1-0.20210815133234-fa23c60d2da1/go.mod h1:EQUSKgW/YaOxmXpAwGiowFDO4i2Rmtk5+9dFyeiymAg=
github.com/wader/readline v0.0.0-20210708114437-6e459499aaf5 h1:lNbk3zDwMc1TaNGWiKrSxCep6R8qqu9CGWBqSFD/9sE=
github.com/wader/readline v0.0.0-20210708114437-6e459499aaf5/go.mod h1:1n88xxtpWULehIaVFcn5JQJy3RUe/5pvJznoiKWfKng=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

View File

@ -69,15 +69,48 @@ func (err HasKeyTypeError) Error() string {
return "cannot check whether " + err.L + " has a key: " + err.R
}
type ArrayIndexTooLargeError struct {
V interface{}
}
func (err *ArrayIndexTooLargeError) Error() string {
return fmt.Sprintf("array index too large: %v", err.V)
}
func expectedArrayOrObject(key interface{}, typ string) error {
switch v := key.(type) {
case string:
return ExpectedObjectWithKeyError{Typ: typ, Key: v}
case int:
return ExpectedArrayWithIndexError{Typ: typ, Index: v}
default:
panic("unreachable")
}
}
type NonUpdatableTypeError struct {
Typ string
Key string
}
func (err NonUpdatableTypeError) Error() string {
return fmt.Sprintf("update key %v cannot be applied to: %s", err.Key, err.Typ)
}
// array
var _ gojq.JQValue = Array{}
type Array []interface{}
func (v Array) JQValueLength() interface{} { return len(v) }
func (v Array) JQValueSliceLen() interface{} { return len(v) }
func (v Array) JQValueIndex(index int) interface{} { return v[index] }
func (v Array) JQValueLength() interface{} { return len(v) }
func (v Array) JQValueSliceLen() interface{} { return len(v) }
func (v Array) JQValueIndex(index int) interface{} {
if index < 0 {
return nil
}
return v[index]
}
func (v Array) JQValueSlice(start int, end int) interface{} { return v[start:end] }
func (v Array) JQValueKey(name string) interface{} {
return ExpectedObjectError{Typ: "array"}
@ -96,6 +129,44 @@ func (v Array) JQValueKeys() interface{} {
}
return vs
}
func (v Array) JQValueUpdate(key interface{}, u interface{}, delpath bool) interface{} {
// TODO: handle {start:, end: }
// TODO: maybe should use gojq implementation as it's quite complex
intKey, ok := key.(int)
if !ok {
return HasKeyTypeError{L: "array", R: fmt.Sprintf("%v", key)}
}
if intKey > 0x3ffffff {
return ArrayIndexTooLargeError{V: intKey}
}
l := len(v)
if intKey >= l {
if delpath {
return v
}
l = intKey + 1
} else if intKey < -l {
if delpath {
return v
}
return FuncTypeError{Name: "setpath", Typ: "number"}
} else if intKey < 0 {
intKey += len(v)
}
var uu []interface{}
if delpath {
uu = append(v[0:intKey], v[intKey+1:]...)
} else {
uu = make([]interface{}, l)
copy(uu, v)
uu[intKey] = u
}
return uu
}
func (v Array) JQValueHas(key interface{}) interface{} {
intKey, ok := key.(int)
if !ok {
@ -125,6 +196,24 @@ func (v Object) JQValueSlice(start int, end int) interface{} {
return ExpectedArrayError{Typ: "object"}
}
func (v Object) JQValueKey(name string) interface{} { return v[name] }
func (v Object) JQValueUpdate(key interface{}, u interface{}, delpath bool) interface{} {
stringKey, ok := key.(string)
if !ok {
return HasKeyTypeError{L: "object", R: fmt.Sprintf("%v", key)}
}
uu := make(map[string]interface{}, len(v))
for kv, vv := range v {
uu[kv] = vv
}
if delpath {
delete(uu, stringKey)
} else {
uu[stringKey] = u
}
return uu
}
func (v Object) JQValueEach() interface{} {
vs := make([]gojq.PathValue, len(v))
i := 0
@ -175,8 +264,11 @@ func (v Number) JQValueSlice(start int, end int) interface{} {
return ExpectedArrayError{Typ: "number"}
}
func (v Number) JQValueKey(name string) interface{} { return ExpectedObjectError{Typ: "number"} }
func (v Number) JQValueEach() interface{} { return IteratorError{Typ: "number"} }
func (v Number) JQValueKeys() interface{} { return FuncTypeError{Name: "keys", Typ: "number"} }
func (v Number) JQValueUpdate(key interface{}, u interface{}, delpath bool) interface{} {
return expectedArrayOrObject(key, "number")
}
func (v Number) JQValueEach() interface{} { return IteratorError{Typ: "number"} }
func (v Number) JQValueKeys() interface{} { return FuncTypeError{Name: "keys", Typ: "number"} }
func (v Number) JQValueHas(key interface{}) interface{} {
return FuncTypeError{Name: "has", Typ: "number"}
}
@ -209,8 +301,11 @@ func (v String) JQValueIndex(index int) interface{} {
}
func (v String) JQValueSlice(start int, end int) interface{} { return string(v[start:end]) }
func (v String) JQValueKey(name string) interface{} { return ExpectedObjectError{Typ: "string"} }
func (v String) JQValueEach() interface{} { return IteratorError{Typ: "string"} }
func (v String) JQValueKeys() interface{} { return FuncTypeError{Name: "keys", Typ: "string"} }
func (v String) JQValueUpdate(key interface{}, u interface{}, delpath bool) interface{} {
return expectedArrayOrObject(key, "string")
}
func (v String) JQValueEach() interface{} { return IteratorError{Typ: "string"} }
func (v String) JQValueKeys() interface{} { return FuncTypeError{Name: "keys", Typ: "string"} }
func (v String) JQValueHas(key interface{}) interface{} {
return FuncTypeError{Name: "has", Typ: "string"}
}
@ -232,8 +327,11 @@ func (v Boolean) JQValueSlice(start int, end int) interface{} {
return ExpectedArrayError{Typ: "boolean"}
}
func (v Boolean) JQValueKey(name string) interface{} { return ExpectedObjectError{Typ: "boolean"} }
func (v Boolean) JQValueEach() interface{} { return IteratorError{Typ: "boolean"} }
func (v Boolean) JQValueKeys() interface{} { return FuncTypeError{Name: "keys", Typ: "boolean"} }
func (v Boolean) JQValueUpdate(key interface{}, u interface{}, delpath bool) interface{} {
return expectedArrayOrObject(key, "boolean")
}
func (v Boolean) JQValueEach() interface{} { return IteratorError{Typ: "boolean"} }
func (v Boolean) JQValueKeys() interface{} { return FuncTypeError{Name: "keys", Typ: "boolean"} }
func (v Boolean) JQValueHas(key interface{}) interface{} {
return FuncTypeError{Name: "has", Typ: "boolean"}
}
@ -260,13 +358,16 @@ func (v Null) JQValueSliceLen() interface{} { return ExpectedArra
func (v Null) JQValueIndex(index int) interface{} { return ExpectedArrayError{Typ: "null"} }
func (v Null) JQValueSlice(start int, end int) interface{} { return ExpectedArrayError{Typ: "null"} }
func (v Null) JQValueKey(name string) interface{} { return ExpectedObjectError{Typ: "null"} }
func (v Null) JQValueEach() interface{} { return IteratorError{Typ: "null"} }
func (v Null) JQValueKeys() interface{} { return FuncTypeError{Name: "keys", Typ: "null"} }
func (v Null) JQValueHas(key interface{}) interface{} { return FuncTypeError{Name: "has", Typ: "null"} }
func (v Null) JQValueType() string { return "null" }
func (v Null) JQValueToNumber() interface{} { return FuncTypeError{Name: "tonumber", Typ: "null"} }
func (v Null) JQValueToString() interface{} { return "null" }
func (v Null) JQValueToGoJQ() interface{} { return nil }
func (v Null) JQValueUpdate(key interface{}, u interface{}, delpath bool) interface{} {
return expectedArrayOrObject(key, "null")
}
func (v Null) JQValueEach() interface{} { return IteratorError{Typ: "null"} }
func (v Null) JQValueKeys() interface{} { return FuncTypeError{Name: "keys", Typ: "null"} }
func (v Null) JQValueHas(key interface{}) interface{} { return FuncTypeError{Name: "has", Typ: "null"} }
func (v Null) JQValueType() string { return "null" }
func (v Null) JQValueToNumber() interface{} { return FuncTypeError{Name: "tonumber", Typ: "null"} }
func (v Null) JQValueToString() interface{} { return "null" }
func (v Null) JQValueToGoJQ() interface{} { return nil }
// Base
@ -285,6 +386,9 @@ func (v Base) JQValueSlice(start int, end int) interface{} { return ExpectedArra
func (v Base) JQValueKey(name string) interface{} {
return ExpectedObjectWithKeyError{Typ: v.Typ, Key: name}
}
func (v Base) JQValueUpdate(key interface{}, u interface{}, delpath bool) interface{} {
return expectedArrayOrObject(key, v.Typ)
}
func (v Base) JQValueEach() interface{} { return IteratorError{Typ: v.Typ} }
func (v Base) JQValueKeys() interface{} { return FuncTypeError{Name: "keys", Typ: v.Typ} }
func (v Base) JQValueHas(key interface{}) interface{} {

View File

@ -142,6 +142,10 @@ func (bo bufferObject) JQValueToGoJQ() interface{} {
return buf.String()
}
func (bo bufferObject) JQValueUpdate(key interface{}, u interface{}, delpath bool) interface{} {
return notUpdateableError{Key: fmt.Sprintf("%v", key), Typ: "buffer"}
}
func (bo bufferObject) Display(w io.Writer, opts Options) error {
if opts.Raw {
if _, err := io.Copy(w, bo.bbr.bb.Copy()); err != nil {

View File

@ -124,7 +124,7 @@ def _prompt:
def _path_prefix:
(._path? // []) | if . == [] then "" else path_to_expr + " " end;
def _preview:
if type != "array" then
if (._format? // false) or type != "array" then
_type_name_error
else
( "["

View File

@ -1,6 +1,6 @@
/test.mp3:
# display
$ fq -d mp3 '.headers | ., tovalue, type, length?' /test.mp3
$ fq -i -d mp3 . /test.mp3
mp3> .headers | ., tovalue, type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f| |.headers: [1]
0x00|49 44 33 04 00 00 00 00 00 23 54 53 53 45 00 00|ID3......#TSSE..| [0]: {} (id3v2)
* |until 0x2c.7 (45) | |
@ -42,8 +42,7 @@ $ fq -d mp3 '.headers | ., tovalue, type, length?' /test.mp3
]
"array"
1
# index
$ fq -d mp3 '.headers[0] | ., type, length?' /test.mp3
mp3> .headers[0] | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f| |.headers[0]: {} (id3v2)
0x00|49 44 33 |ID3 | magic: "ID3" (Correct)
0x00| 04 | . | version: 4
@ -56,24 +55,23 @@ $ fq -d mp3 '.headers[0] | ., type, length?' /test.mp3
0x20| 00 00 00 00 00 00 00 00 00 00 | .......... | padding: Correct (none) (zero padding)
"object"
7
$ fq -d mp3 '.headers[-1000] | ., type, length?' /test.mp3
mp3> .headers[-1000] | ., type, length?
null
"null"
0
$ fq -d mp3 '.headers[1000] | ., type, length?' /test.mp3
mp3> .headers[1000] | ., type, length?
null
"null"
0
# slice
$ fq -d mp3 '.headers[1:3] | ., type, length?' /test.mp3
mp3> .headers[1:3] | ., type, length?
[]
"array"
0
$ fq -d mp3 '.headers[0:-1] | ., type, length?' /test.mp3
mp3> .headers[0:-1] | ., type, length?
[]
"array"
0
$ fq -d mp3 '.headers[-1000:2000] | ., type, length?' /test.mp3
mp3> .headers[-1000:2000] | ., type, length?
[
{
"flags": {
@ -112,96 +110,92 @@ $ fq -d mp3 '.headers[-1000:2000] | ., type, length?' /test.mp3
]
"array"
1
# key
$ fq -d mp3 '.headers["test"] | ., type, length?' /test.mp3
exitcode: 5
stderr:
mp3> .headers["test"] | ., type, length?
error: expected an object with key "test" but got: array
# each
$ fq -d mp3 '[.headers[]] | type, length?' /test.mp3
mp3> [.headers[]] | type, length?
"array"
1
# keys
$ fq -d mp3 '.headers | keys' /test.mp3
mp3> .headers | keys
[
0
]
# has
$ fq -d mp3 '.headers | has("a")' /test.mp3
exitcode: 5
stderr:
mp3> .headers | has("a")
error: cannot check whether array has a key: a
$ fq -d mp3 '.headers | has(0)' /test.mp3
mp3> .headers | has(0)
true
# type
$ fq -d mp3 '.headers | type' /test.mp3
mp3> .headers | type
"array"
# tonumber
$ fq -d mp3 '.headers | tonumber' /test.mp3
exitcode: 5
stderr:
mp3> .headers | tonumber
error: tonumber cannot be applied to: array
# tostring
$ fq -d mp3 '.headers | tostring' /test.mp3
exitcode: 5
stderr:
mp3> .headers | tostring
error: tostring cannot be applied to: array
# to gojq
$ fq -d mp3 '.headers + ""' /test.mp3
exitcode: 5
stderr:
mp3> .headers + ""
error: cannot add: array ([{"flags":{"experimental_ ...]) and string ("")
$ fq -d mp3 '.headers + 1' /test.mp3
exitcode: 5
stderr:
mp3> .headers + 1
error: cannot add: array ([{"flags":{"experimental_ ...]) and number (1)
# test _keys
$ fq -d mp3 '.headers._start | ., type, length?' /test.mp3
mp3> .headers._start | ., type, length?
0
"number"
0
$ fq -d mp3 '.headers._stop | ., type, length?' /test.mp3
mp3> .headers._stop | ., type, length?
360
"number"
360
$ fq -d mp3 '.headers._len | ., type, length?' /test.mp3
mp3> .headers._len | ., type, length?
360
"number"
360
$ fq -d mp3 '.headers._name | ., type, length?' /test.mp3
mp3> .headers._name | ., type, length?
"headers"
"string"
7
$ fq -d mp3 '.headers._symbol | ., type, length?' /test.mp3
mp3> .headers._symbol | ., type, length?
""
"string"
0
$ fq -d mp3 '.headers._description | ., type, length?' /test.mp3
mp3> .headers._description | ., type, length?
""
"string"
0
$ fq -d mp3 '.headers._path | ., type, length?' /test.mp3
mp3> .headers._path | ., type, length?
[
"headers"
]
"array"
1
$ fq -d mp3 '.headers._bits | ., type, length?' /test.mp3
mp3> .headers._bits | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f| |
0x00|49 44 33 04 00 00 00 00 00 23 54 53 53 45 00 00|ID3......#TSSE..|
<360 bits>
"buffer"
360
$ fq -d mp3 '.headers._bytes | ., type, length?' /test.mp3
mp3> .headers._bytes | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f| |
0x00|49 44 33 04 00 00 00 00 00 23 54 53 53 45 00 00|ID3......#TSSE..|
<45 bytes>
"buffer"
45
$ fq -d mp3 '.headers._error | ., type, length?' /test.mp3
mp3> .headers._error | ., type, length?
null
"null"
0
$ fq -d mp3 '.headers._unknown | ., type, length?' /test.mp3
mp3> .headers._unknown | ., type, length?
false
"boolean"
mp3> .headers.a = 1
error: cannot update key a for array
mp3> .headers[0] = 1
error: cannot update key 0 for array
mp3> .headers.a |= empty
error: expected an object with key "a" but got: array
mp3> .headers[0] |= empty
error: cannot update key 0 for array
mp3> .headers | setpath(["a"]; 1)
error: cannot update key a for array
mp3> .headers | setpath([0]; 1)
error: cannot update key 0 for array
mp3> .headers | delpaths([["a"]])
error: cannot update key a for array
mp3> .headers | delpaths([[0]])
error: cannot update key 0 for array
mp3> ^D

View File

@ -1,106 +1,67 @@
/test.mp3:
# display
$ fq -d mp3 '.headers[0].flags.unsynchronisation | ., tovalue, type, length?' /test.mp3
$ fq -i -d mp3 . /test.mp3
mp3> .headers[0].flags.unsynchronisation | ., tovalue, type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f| |
0x0| 00 | . |.headers[0].flags.unsynchronisation: false
false
"boolean"
# index
$ fq -d mp3 '.headers[0].flags.unsynchronisation[0] | ., type, length?' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].flags.unsynchronisation[0] | ., type, length?
error: expected an array but got: boolean
$ fq -d mp3 '.headers[0].flags.unsynchronisation[-1000] | ., type, length?' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].flags.unsynchronisation[-1000] | ., type, length?
error: expected an array but got: boolean
$ fq -d mp3 '.headers[0].flags.unsynchronisation[1000] | ., type, length?' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].flags.unsynchronisation[1000] | ., type, length?
error: expected an array but got: boolean
# slice
$ fq -d mp3 '.headers[0].flags.unsynchronisation[1:3] | ., type, length?' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].flags.unsynchronisation[1:3] | ., type, length?
error: expected an array but got: boolean
$ fq -d mp3 '.headers[0].flags.unsynchronisation[0:-1] | ., type, length?' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].flags.unsynchronisation[0:-1] | ., type, length?
error: expected an array but got: boolean
$ fq -d mp3 '.headers[0].flags.unsynchronisation[-1000:2000] | ., type, length?' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].flags.unsynchronisation[-1000:2000] | ., type, length?
error: expected an array but got: boolean
# key
$ fq -d mp3 '.headers[0].flags.unsynchronisation["test"] | ., type, length?' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].flags.unsynchronisation["test"] | ., type, length?
error: expected an object but got: boolean
# each
$ fq -d mp3 '[.headers[0].flags.unsynchronisation[]] | type, length?' /test.mp3
exitcode: 5
stderr:
mp3> [.headers[0].flags.unsynchronisation[]] | type, length?
error: cannot iterate over: boolean
# keys
$ fq -d mp3 '.headers[0].flags.unsynchronisation | keys' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].flags.unsynchronisation | keys
error: keys cannot be applied to: boolean
# has
$ fq -d mp3 '.headers[0].flags.unsynchronisation | has("a")' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].flags.unsynchronisation | has("a")
error: has cannot be applied to: boolean
$ fq -d mp3 '.headers[0].flags.unsynchronisation | has(0)' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].flags.unsynchronisation | has(0)
error: has cannot be applied to: boolean
# type
$ fq -d mp3 '.headers[0].flags.unsynchronisation | type' /test.mp3
mp3> .headers[0].flags.unsynchronisation | type
"boolean"
# tonumber
$ fq -d mp3 '.headers[0].flags.unsynchronisation | tonumber' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].flags.unsynchronisation | tonumber
error: tonumber cannot be applied to: boolean
# tostring
$ fq -d mp3 '.headers[0].flags.unsynchronisation | tostring' /test.mp3
mp3> .headers[0].flags.unsynchronisation | tostring
"false"
# to gojq
$ fq -d mp3 '.headers[0].flags.unsynchronisation + ""' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].flags.unsynchronisation + ""
error: cannot add: boolean (false) and string ("")
$ fq -d mp3 '.headers[0].flags.unsynchronisation + 1' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].flags.unsynchronisation + 1
error: cannot add: boolean (false) and number (1)
# test _keys
$ fq -d mp3 '.headers[0].flags.unsynchronisation._start | ., type, length?' /test.mp3
mp3> .headers[0].flags.unsynchronisation._start | ., type, length?
40
"number"
40
$ fq -d mp3 '.headers[0].flags.unsynchronisation._stop | ., type, length?' /test.mp3
mp3> .headers[0].flags.unsynchronisation._stop | ., type, length?
41
"number"
41
$ fq -d mp3 '.headers[0].flags.unsynchronisation._len | ., type, length?' /test.mp3
mp3> .headers[0].flags.unsynchronisation._len | ., type, length?
1
"number"
1
$ fq -d mp3 '.headers[0].flags.unsynchronisation._name | ., type, length?' /test.mp3
mp3> .headers[0].flags.unsynchronisation._name | ., type, length?
"unsynchronisation"
"string"
17
$ fq -d mp3 '.headers[0].flags.unsynchronisation._symbol | ., type, length?' /test.mp3
mp3> .headers[0].flags.unsynchronisation._symbol | ., type, length?
""
"string"
0
$ fq -d mp3 '.headers[0].flags.unsynchronisation._description | ., type, length?' /test.mp3
mp3> .headers[0].flags.unsynchronisation._description | ., type, length?
""
"string"
0
$ fq -d mp3 '.headers[0].flags.unsynchronisation._path | ., type, length?' /test.mp3
mp3> .headers[0].flags.unsynchronisation._path | ., type, length?
[
"headers",
0,
@ -109,22 +70,39 @@ $ fq -d mp3 '.headers[0].flags.unsynchronisation._path | ., type, length?' /test
]
"array"
4
$ fq -d mp3 '.headers[0].flags.unsynchronisation._bits | ., type, length?' /test.mp3
mp3> .headers[0].flags.unsynchronisation._bits | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f| |
0x0|00 |. |
<1 bits>
"buffer"
1
$ fq -d mp3 '.headers[0].flags.unsynchronisation._bytes | ., type, length?' /test.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| |
0x0|00 |. |
<0 bytes>
"buffer"
0
$ fq -d mp3 '.headers[0].flags.unsynchronisation._error | ., type, length?' /test.mp3
mp3> .headers[0].flags.unsynchronisation._error | ., type, length?
null
"null"
0
$ fq -d mp3 '.headers[0].flags.unsynchronisation._unknown | ., type, length?' /test.mp3
mp3> .headers[0].flags.unsynchronisation._unknown | ., type, length?
false
"boolean"
mp3> .headers[0].flags.unsynchronisation.a = 1
error: expected an object but got: boolean
mp3> .headers[0].flags.unsynchronisation[0] = 1
error: expected an array but got: boolean
mp3> .headers[0].flags.unsynchronisation.a |= empty
error: expected an object but got: boolean
mp3> .headers[0].flags.unsynchronisation[0] |= empty
error: expected an array but got: boolean
mp3> .headers[0].flags.unsynchronisation | setpath(["a"]; 1)
error: expected an object with key "a" but got: boolean
mp3> .headers[0].flags.unsynchronisation | setpath([0]; 1)
error: expected an array with index 0 but got: boolean
mp3> .headers[0].flags.unsynchronisation | delpaths([["a"]])
error: expected an object with key "a" but got: boolean
mp3> .headers[0].flags.unsynchronisation | delpaths([[0]])
error: expected an array with index 0 but got: boolean
mp3> ^D

View File

@ -0,0 +1,121 @@
/test.mp3:
$ fq -i -n '"[]" | json'
json> (.) | ., tovalue, type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f| |
| | |.: [0] unnamed (json)
[]
"array"
0
json> (.)[0] | ., type, length?
null
"null"
0
json> (.)[-1000] | ., type, length?
null
"null"
0
json> (.)[1000] | ., type, length?
null
"null"
0
json> (.)[1:3] | ., type, length?
[]
"array"
0
json> (.)[0:-1] | ., type, length?
[]
"array"
0
json> (.)[-1000:2000] | ., type, length?
[]
"array"
0
json> (.)["test"] | ., type, length?
error: expected an object but got: array
json> [(.)[]] | type, length?
"array"
0
json> (.) | keys
[]
json> (.) | has("a")
error: cannot check whether array has a key: a
json> (.) | has(0)
false
json> (.) | type
"array"
json> (.) | tonumber
error: tonumber cannot be applied to: array
json> (.) | tostring
error: tostring cannot be applied to: array
json> (.) + ""
error: cannot add: array ([]) and string ("")
json> (.) + 1
error: cannot add: array ([]) and number (1)
json> (.)._start | ., type, length?
0
"number"
0
json> (.)._stop | ., type, length?
16
"number"
16
json> (.)._len | ., type, length?
16
"number"
16
json> (.)._name | ., type, length?
""
"string"
0
json> (.)._symbol | ., type, length?
""
"string"
0
json> (.)._description | ., type, length?
"unnamed"
"string"
7
json> (.)._path | ., type, length?
[]
"array"
0
json> (.)._bits | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f| |
0x0|5b 5d |[] |
<16 bits>
"buffer"
16
json> (.)._bytes | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f| |
0x0|5b 5d |[] |
<2 bytes>
"buffer"
2
json> (.)._error | ., type, length?
null
"null"
0
json> (.)._unknown | ., type, length?
false
"boolean"
json> (.).a = 1
error: expected an object but got: array
json> (.)[0] = 1
[
1
]
json> (.).a |= empty
error: expected an object but got: array
json> (.)[0] |= empty
[]
json> (.) | setpath(["a"]; 1)
error: cannot check whether array has a key: a
json> (.) | setpath([0]; 1)
[
1
]
json> (.) | delpaths([["a"]])
error: cannot check whether array has a key: a
json> (.) | delpaths([[0]])
[]
json> ^D

View File

@ -0,0 +1,111 @@
/test.mp3:
$ fq -i -n '"{}" | json'
json> (.) | ., tovalue, type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f| |
| | |.: {} unnamed (json)
{}
"object"
0
json> (.)[0] | ., type, length?
error: expected an array but got: object
json> (.)[-1000] | ., type, length?
error: expected an array but got: object
json> (.)[1000] | ., type, length?
error: expected an array but got: object
json> (.)[1:3] | ., type, length?
error: expected an array but got: object
json> (.)[0:-1] | ., type, length?
error: expected an array but got: object
json> (.)[-1000:2000] | ., type, length?
error: expected an array but got: object
json> (.)["test"] | ., type, length?
null
"null"
0
json> [(.)[]] | type, length?
"array"
0
json> (.) | keys
[]
json> (.) | has("a")
false
json> (.) | has(0)
error: cannot check whether object has a key: 0
json> (.) | type
"object"
json> (.) | tonumber
error: tonumber cannot be applied to: object
json> (.) | tostring
error: tostring cannot be applied to: object
json> (.) + ""
error: cannot add: object ({}) and string ("")
json> (.) + 1
error: cannot add: object ({}) and number (1)
json> (.)._start | ., type, length?
0
"number"
0
json> (.)._stop | ., type, length?
16
"number"
16
json> (.)._len | ., type, length?
16
"number"
16
json> (.)._name | ., type, length?
""
"string"
0
json> (.)._symbol | ., type, length?
""
"string"
0
json> (.)._description | ., type, length?
"unnamed"
"string"
7
json> (.)._path | ., type, length?
[]
"array"
0
json> (.)._bits | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f| |
0x0|7b 7d |{} |
<16 bits>
"buffer"
16
json> (.)._bytes | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f| |
0x0|7b 7d |{} |
<2 bytes>
"buffer"
2
json> (.)._error | ., type, length?
null
"null"
0
json> (.)._unknown | ., type, length?
false
"boolean"
json> (.).a = 1
{
"a": 1
}
json> (.)[0] = 1
error: expected an array but got: object
json> (.).a |= empty
{}
json> (.)[0] |= empty
error: expected an array but got: object
json> (.) | setpath(["a"]; 1)
{
"a": 1
}
json> (.) | setpath([0]; 1)
error: cannot check whether object has a key: 0
json> (.) | delpaths([["a"]])
{}
json> (.) | delpaths([[0]])
error: cannot check whether object has a key: 0
json> ^D

View File

@ -1,103 +1,68 @@
/test.mp3:
# display
$ fq -d mp3 '.headers[0].padding | ., tovalue, type, length?' /test.mp3
$ fq -i -d mp3 . /test.mp3
mp3> .headers[0].padding | ., tovalue, type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f| |
0x20| 00 00 00 00 00 00 00 00 00 00 | .......... |.headers[0].padding: Correct (none) (zero padding)
null
"null"
0
# index
$ fq -d mp3 '.headers[0].padding[0] | ., type, length?' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].padding[0] | ., type, length?
error: expected an array but got: null
$ fq -d mp3 '.headers[0].padding[-1000] | ., type, length?' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].padding[-1000] | ., type, length?
error: expected an array but got: null
$ fq -d mp3 '.headers[0].padding[1000] | ., type, length?' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].padding[1000] | ., type, length?
error: expected an array but got: null
# slice
$ fq -d mp3 '.headers[0].padding[1:3] | ., type, length?' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].padding[1:3] | ., type, length?
error: expected an array but got: null
$ fq -d mp3 '.headers[0].padding[0:-1] | ., type, length?' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].padding[0:-1] | ., type, length?
error: expected an array but got: null
$ fq -d mp3 '.headers[0].padding[-1000:2000] | ., type, length?' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].padding[-1000:2000] | ., type, length?
error: expected an array but got: null
# key
$ fq -d mp3 '.headers[0].padding["test"] | ., type, length?' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].padding["test"] | ., type, length?
error: expected an object but got: null
# each
$ fq -d mp3 '[.headers[0].padding[]] | type, length?' /test.mp3
exitcode: 5
stderr:
mp3> [.headers[0].padding[]] | type, length?
error: cannot iterate over: null
# keys
$ fq -d mp3 '.headers[0].padding | keys' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].padding | keys
error: keys cannot be applied to: null
# has
$ fq -d mp3 '.headers[0].padding | has("a")' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].padding | has("a")
error: has cannot be applied to: null
$ fq -d mp3 '.headers[0].padding | has(0)' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].padding | has(0)
error: has cannot be applied to: null
# type
$ fq -d mp3 '.headers[0].padding | type' /test.mp3
mp3> .headers[0].padding | type
"null"
# tonumber
$ fq -d mp3 '.headers[0].padding | tonumber' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].padding | tonumber
error: tonumber cannot be applied to: null
# tostring
$ fq -d mp3 '.headers[0].padding | tostring' /test.mp3
mp3> .headers[0].padding | tostring
"null"
# to gojq
$ fq -d mp3 '.headers[0].padding + ""' /test.mp3
mp3> .headers[0].padding + ""
""
$ fq -d mp3 '.headers[0].padding + 1' /test.mp3
mp3> .headers[0].padding + 1
1
# test _keys
$ fq -d mp3 '.headers[0].padding._start | ., type, length?' /test.mp3
mp3> .headers[0].padding._start | ., type, length?
280
"number"
280
$ fq -d mp3 '.headers[0].padding._stop | ., type, length?' /test.mp3
mp3> .headers[0].padding._stop | ., type, length?
360
"number"
360
$ fq -d mp3 '.headers[0].padding._len | ., type, length?' /test.mp3
mp3> .headers[0].padding._len | ., type, length?
80
"number"
80
$ fq -d mp3 '.headers[0].padding._name | ., type, length?' /test.mp3
mp3> .headers[0].padding._name | ., type, length?
"padding"
"string"
7
$ fq -d mp3 '.headers[0].padding._symbol | ., type, length?' /test.mp3
mp3> .headers[0].padding._symbol | ., type, length?
"Correct"
"string"
7
$ fq -d mp3 '.headers[0].padding._description | ., type, length?' /test.mp3
mp3> .headers[0].padding._description | ., type, length?
"zero padding"
"string"
12
$ fq -d mp3 '.headers[0].padding._path | ., type, length?' /test.mp3
mp3> .headers[0].padding._path | ., type, length?
[
"headers",
0,
@ -105,22 +70,39 @@ $ fq -d mp3 '.headers[0].padding._path | ., type, length?' /test.mp3
]
"array"
3
$ fq -d mp3 '.headers[0].padding._bits | ., type, length?' /test.mp3
mp3> .headers[0].padding._bits | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f| |
0x0|00 00 00 00 00 00 00 00 00 00 |.......... |
<80 bits>
"buffer"
80
$ fq -d mp3 '.headers[0].padding._bytes | ., type, length?' /test.mp3
mp3> .headers[0].padding._bytes | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f| |
0x0|00 00 00 00 00 00 00 00 00 00 |.......... |
<10 bytes>
"buffer"
10
$ fq -d mp3 '.headers[0].padding._error | ., type, length?' /test.mp3
mp3> .headers[0].padding._error | ., type, length?
null
"null"
0
$ fq -d mp3 '.headers[0].padding._unknown | ., type, length?' /test.mp3
mp3> .headers[0].padding._unknown | ., type, length?
false
"boolean"
mp3> .headers[0].padding.a = 1
error: expected an object but got: null
mp3> .headers[0].padding[0] = 1
error: expected an array but got: null
mp3> .headers[0].padding.a |= empty
error: expected an object but got: null
mp3> .headers[0].padding[0] |= empty
error: expected an array but got: null
mp3> .headers[0].padding | setpath(["a"]; 1)
error: expected an object with key "a" but got: null
mp3> .headers[0].padding | setpath([0]; 1)
error: expected an array with index 0 but got: null
mp3> .headers[0].padding | delpaths([["a"]])
error: expected an object with key "a" but got: null
mp3> .headers[0].padding | delpaths([[0]])
error: expected an array with index 0 but got: null
mp3> ^D

View File

@ -1,103 +1,68 @@
/test.mp3:
# display
$ fq -d mp3 '.headers[0].version | ., tovalue, type, length?' /test.mp3
$ fq -i -d mp3 . /test.mp3
mp3> .headers[0].version | ., tovalue, type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f| |
0x0| 04 | . |.headers[0].version: 4
4
"number"
4
# index
$ fq -d mp3 '.headers[0].version[0] | ., type, length?' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].version[0] | ., type, length?
error: expected an array but got: number
$ fq -d mp3 '.headers[0].version[-1000] | ., type, length?' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].version[-1000] | ., type, length?
error: expected an array but got: number
$ fq -d mp3 '.headers[0].version[1000] | ., type, length?' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].version[1000] | ., type, length?
error: expected an array but got: number
# slice
$ fq -d mp3 '.headers[0].version[1:3] | ., type, length?' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].version[1:3] | ., type, length?
error: expected an array but got: number
$ fq -d mp3 '.headers[0].version[0:-1] | ., type, length?' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].version[0:-1] | ., type, length?
error: expected an array but got: number
$ fq -d mp3 '.headers[0].version[-1000:2000] | ., type, length?' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].version[-1000:2000] | ., type, length?
error: expected an array but got: number
# key
$ fq -d mp3 '.headers[0].version["test"] | ., type, length?' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].version["test"] | ., type, length?
error: expected an object but got: number
# each
$ fq -d mp3 '[.headers[0].version[]] | type, length?' /test.mp3
exitcode: 5
stderr:
mp3> [.headers[0].version[]] | type, length?
error: cannot iterate over: number
# keys
$ fq -d mp3 '.headers[0].version | keys' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].version | keys
error: keys cannot be applied to: number
# has
$ fq -d mp3 '.headers[0].version | has("a")' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].version | has("a")
error: has cannot be applied to: number
$ fq -d mp3 '.headers[0].version | has(0)' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].version | has(0)
error: has cannot be applied to: number
# type
$ fq -d mp3 '.headers[0].version | type' /test.mp3
mp3> .headers[0].version | type
"number"
# tonumber
$ fq -d mp3 '.headers[0].version | tonumber' /test.mp3
mp3> .headers[0].version | tonumber
4
# tostring
$ fq -d mp3 '.headers[0].version | tostring' /test.mp3
mp3> .headers[0].version | tostring
"4"
# to gojq
$ fq -d mp3 '.headers[0].version + ""' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].version + ""
error: cannot add: number (4) and string ("")
$ fq -d mp3 '.headers[0].version + 1' /test.mp3
mp3> .headers[0].version + 1
5
# test _keys
$ fq -d mp3 '.headers[0].version._start | ., type, length?' /test.mp3
mp3> .headers[0].version._start | ., type, length?
24
"number"
24
$ fq -d mp3 '.headers[0].version._stop | ., type, length?' /test.mp3
mp3> .headers[0].version._stop | ., type, length?
32
"number"
32
$ fq -d mp3 '.headers[0].version._len | ., type, length?' /test.mp3
mp3> .headers[0].version._len | ., type, length?
8
"number"
8
$ fq -d mp3 '.headers[0].version._name | ., type, length?' /test.mp3
mp3> .headers[0].version._name | ., type, length?
"version"
"string"
7
$ fq -d mp3 '.headers[0].version._symbol | ., type, length?' /test.mp3
mp3> .headers[0].version._symbol | ., type, length?
""
"string"
0
$ fq -d mp3 '.headers[0].version._description | ., type, length?' /test.mp3
mp3> .headers[0].version._description | ., type, length?
""
"string"
0
$ fq -d mp3 '.headers[0].version._path | ., type, length?' /test.mp3
mp3> .headers[0].version._path | ., type, length?
[
"headers",
0,
@ -105,22 +70,39 @@ $ fq -d mp3 '.headers[0].version._path | ., type, length?' /test.mp3
]
"array"
3
$ fq -d mp3 '.headers[0].version._bits | ., type, length?' /test.mp3
mp3> .headers[0].version._bits | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f| |
0x0|04 |. |
<8 bits>
"buffer"
8
$ fq -d mp3 '.headers[0].version._bytes | ., type, length?' /test.mp3
mp3> .headers[0].version._bytes | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f| |
0x0|04 |. |
<1 bytes>
"buffer"
1
$ fq -d mp3 '.headers[0].version._error | ., type, length?' /test.mp3
mp3> .headers[0].version._error | ., type, length?
null
"null"
0
$ fq -d mp3 '.headers[0].version._unknown | ., type, length?' /test.mp3
mp3> .headers[0].version._unknown | ., type, length?
false
"boolean"
mp3> .headers[0].version.a = 1
error: expected an object but got: number
mp3> .headers[0].version[0] = 1
error: expected an array but got: number
mp3> .headers[0].version.a |= empty
error: expected an object but got: number
mp3> .headers[0].version[0] |= empty
error: expected an array but got: number
mp3> .headers[0].version | setpath(["a"]; 1)
error: expected an object with key "a" but got: number
mp3> .headers[0].version | setpath([0]; 1)
error: expected an array with index 0 but got: number
mp3> .headers[0].version | delpaths([["a"]])
error: expected an object with key "a" but got: number
mp3> .headers[0].version | delpaths([[0]])
error: expected an array with index 0 but got: number
mp3> ^D

View File

@ -1,6 +1,6 @@
/test.mp3:
# display
$ fq -d mp3 '.headers[0].flags | ., tovalue, type, length?' /test.mp3
$ fq -i -d mp3 . /test.mp3
mp3> .headers[0].flags | ., tovalue, type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f| |.headers[0].flags: {}
0x0| 00 | . | unsynchronisation: false
0x0| 00 | . | extended_header: false
@ -14,104 +14,71 @@ $ fq -d mp3 '.headers[0].flags | ., tovalue, type, length?' /test.mp3
}
"object"
4
# index
$ fq -d mp3 '.headers[0].flags[0] | ., type, length?' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].flags[0] | ., type, length?
error: expected an array with index 0 but got: object
$ fq -d mp3 '.headers[0].flags[-1000] | ., type, length?' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].flags[-1000] | ., type, length?
error: expected an array with index -2 but got: object
$ fq -d mp3 '.headers[0].flags[1000] | ., type, length?' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].flags[1000] | ., type, length?
error: expected an array with index -1 but got: object
# slice
$ fq -d mp3 '.headers[0].flags[1:3] | ., type, length?' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].flags[1:3] | ., type, length?
error: expected an array but got: object
$ fq -d mp3 '.headers[0].flags[0:-1] | ., type, length?' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].flags[0:-1] | ., type, length?
error: expected an array but got: object
$ fq -d mp3 '.headers[0].flags[-1000:2000] | ., type, length?' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].flags[-1000:2000] | ., type, length?
error: expected an array but got: object
# key
$ fq -d mp3 '.headers[0].flags["test"] | ., type, length?' /test.mp3
mp3> .headers[0].flags["test"] | ., type, length?
null
"null"
0
# each
$ fq -d mp3 '[.headers[0].flags[]] | type, length?' /test.mp3
mp3> [.headers[0].flags[]] | type, length?
"array"
4
# keys
$ fq -d mp3 '.headers[0].flags | keys' /test.mp3
mp3> .headers[0].flags | keys
[
"unsynchronisation",
"extended_header",
"experimental_indicator",
"unused"
]
# has
$ fq -d mp3 '.headers[0].flags | has("a")' /test.mp3
mp3> .headers[0].flags | has("a")
false
$ fq -d mp3 '.headers[0].flags | has(0)' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].flags | has(0)
error: cannot check whether object has a key: 0
# type
$ fq -d mp3 '.headers[0].flags | type' /test.mp3
mp3> .headers[0].flags | type
"object"
# tonumber
$ fq -d mp3 '.headers[0].flags | tonumber' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].flags | tonumber
error: tonumber cannot be applied to: object
# tostring
$ fq -d mp3 '.headers[0].flags | tostring' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].flags | tostring
error: tostring cannot be applied to: object
# to gojq
$ fq -d mp3 '.headers[0].flags + ""' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].flags + ""
error: cannot add: object ({"experimental_indicator" ...}) and string ("")
$ fq -d mp3 '.headers[0].flags + 1' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].flags + 1
error: cannot add: object ({"experimental_indicator" ...}) and number (1)
# test _keys
$ fq -d mp3 '.headers[0].flags._start | ., type, length?' /test.mp3
mp3> .headers[0].flags._start | ., type, length?
40
"number"
40
$ fq -d mp3 '.headers[0].flags._stop | ., type, length?' /test.mp3
mp3> .headers[0].flags._stop | ., type, length?
48
"number"
48
$ fq -d mp3 '.headers[0].flags._len | ., type, length?' /test.mp3
mp3> .headers[0].flags._len | ., type, length?
8
"number"
8
$ fq -d mp3 '.headers[0].flags._name | ., type, length?' /test.mp3
mp3> .headers[0].flags._name | ., type, length?
"flags"
"string"
5
$ fq -d mp3 '.headers[0].flags._symbol | ., type, length?' /test.mp3
mp3> .headers[0].flags._symbol | ., type, length?
""
"string"
0
$ fq -d mp3 '.headers[0].flags._description | ., type, length?' /test.mp3
mp3> .headers[0].flags._description | ., type, length?
""
"string"
0
$ fq -d mp3 '.headers[0].flags._path | ., type, length?' /test.mp3
mp3> .headers[0].flags._path | ., type, length?
[
"headers",
0,
@ -119,22 +86,39 @@ $ fq -d mp3 '.headers[0].flags._path | ., type, length?' /test.mp3
]
"array"
3
$ fq -d mp3 '.headers[0].flags._bits | ., type, length?' /test.mp3
mp3> .headers[0].flags._bits | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f| |
0x0|00 |. |
<8 bits>
"buffer"
8
$ fq -d mp3 '.headers[0].flags._bytes | ., type, length?' /test.mp3
mp3> .headers[0].flags._bytes | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f| |
0x0|00 |. |
<1 bytes>
"buffer"
1
$ fq -d mp3 '.headers[0].flags._error | ., type, length?' /test.mp3
mp3> .headers[0].flags._error | ., type, length?
null
"null"
0
$ fq -d mp3 '.headers[0].flags._unknown | ., type, length?' /test.mp3
mp3> .headers[0].flags._unknown | ., type, length?
false
"boolean"
mp3> .headers[0].flags.a = 1
error: cannot update key a for object
mp3> .headers[0].flags[0] = 1
error: expected an array with index 0 but got: object
mp3> .headers[0].flags.a |= empty
error: cannot update key a for object
mp3> .headers[0].flags[0] |= empty
error: expected an array with index 0 but got: object
mp3> .headers[0].flags | setpath(["a"]; 1)
error: cannot update key a for object
mp3> .headers[0].flags | setpath([0]; 1)
error: cannot update key 0 for object
mp3> .headers[0].flags | delpaths([["a"]])
error: cannot update key a for object
mp3> .headers[0].flags | delpaths([[0]])
error: cannot update key 0 for object
mp3> ^D

View File

@ -1,105 +1,80 @@
/test.mp3:
# display
$ fq -d mp3 '.headers[0].magic | ., tovalue, type, length?' /test.mp3
$ fq -i -d mp3 . /test.mp3
mp3> .headers[0].magic | ., tovalue, type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f| |
0x0|49 44 33 |ID3 |.headers[0].magic: "ID3" (Correct)
"ID3"
"string"
3
# index
$ fq -d mp3 '.headers[0].magic[0] | ., type, length?' /test.mp3
mp3> .headers[0].magic[0] | ., type, length?
"I"
"string"
1
$ fq -d mp3 '.headers[0].magic[-1000] | ., type, length?' /test.mp3
mp3> .headers[0].magic[-1000] | ., type, length?
""
"string"
0
$ fq -d mp3 '.headers[0].magic[1000] | ., type, length?' /test.mp3
mp3> .headers[0].magic[1000] | ., type, length?
""
"string"
0
# slice
$ fq -d mp3 '.headers[0].magic[1:3] | ., type, length?' /test.mp3
mp3> .headers[0].magic[1:3] | ., type, length?
"D3"
"string"
2
$ fq -d mp3 '.headers[0].magic[0:-1] | ., type, length?' /test.mp3
mp3> .headers[0].magic[0:-1] | ., type, length?
"ID"
"string"
2
$ fq -d mp3 '.headers[0].magic[-1000:2000] | ., type, length?' /test.mp3
mp3> .headers[0].magic[-1000:2000] | ., type, length?
"ID3"
"string"
3
# key
$ fq -d mp3 '.headers[0].magic["test"] | ., type, length?' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].magic["test"] | ., type, length?
error: expected an object but got: string
# each
$ fq -d mp3 '[.headers[0].magic[]] | type, length?' /test.mp3
exitcode: 5
stderr:
mp3> [.headers[0].magic[]] | type, length?
error: cannot iterate over: string
# keys
$ fq -d mp3 '.headers[0].magic | keys' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].magic | keys
error: keys cannot be applied to: string
# has
$ fq -d mp3 '.headers[0].magic | has("a")' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].magic | has("a")
error: has cannot be applied to: string
$ fq -d mp3 '.headers[0].magic | has(0)' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].magic | has(0)
error: has cannot be applied to: string
# type
$ fq -d mp3 '.headers[0].magic | type' /test.mp3
mp3> .headers[0].magic | type
"string"
# tonumber
$ fq -d mp3 '.headers[0].magic | tonumber' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].magic | tonumber
error: invalid number: "ID3"
# tostring
$ fq -d mp3 '.headers[0].magic | tostring' /test.mp3
mp3> .headers[0].magic | tostring
"ID3"
# to gojq
$ fq -d mp3 '.headers[0].magic + ""' /test.mp3
mp3> .headers[0].magic + ""
"ID3"
$ fq -d mp3 '.headers[0].magic + 1' /test.mp3
exitcode: 5
stderr:
mp3> .headers[0].magic + 1
error: cannot add: string ("ID3") and number (1)
# test _keys
$ fq -d mp3 '.headers[0].magic._start | ., type, length?' /test.mp3
mp3> .headers[0].magic._start | ., type, length?
0
"number"
0
$ fq -d mp3 '.headers[0].magic._stop | ., type, length?' /test.mp3
mp3> .headers[0].magic._stop | ., type, length?
24
"number"
24
$ fq -d mp3 '.headers[0].magic._len | ., type, length?' /test.mp3
mp3> .headers[0].magic._len | ., type, length?
24
"number"
24
$ fq -d mp3 '.headers[0].magic._name | ., type, length?' /test.mp3
mp3> .headers[0].magic._name | ., type, length?
"magic"
"string"
5
$ fq -d mp3 '.headers[0].magic._symbol | ., type, length?' /test.mp3
mp3> .headers[0].magic._symbol | ., type, length?
""
"string"
0
$ fq -d mp3 '.headers[0].magic._description | ., type, length?' /test.mp3
mp3> .headers[0].magic._description | ., type, length?
"Correct"
"string"
7
$ fq -d mp3 '.headers[0].magic._path | ., type, length?' /test.mp3
mp3> .headers[0].magic._path | ., type, length?
[
"headers",
0,
@ -107,22 +82,39 @@ $ fq -d mp3 '.headers[0].magic._path | ., type, length?' /test.mp3
]
"array"
3
$ fq -d mp3 '.headers[0].magic._bits | ., type, length?' /test.mp3
mp3> .headers[0].magic._bits | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f| |
0x0|49 44 33 |ID3 |
<24 bits>
"buffer"
24
$ fq -d mp3 '.headers[0].magic._bytes | ., type, length?' /test.mp3
mp3> .headers[0].magic._bytes | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f| |
0x0|49 44 33 |ID3 |
<3 bytes>
"buffer"
3
$ fq -d mp3 '.headers[0].magic._error | ., type, length?' /test.mp3
mp3> .headers[0].magic._error | ., type, length?
null
"null"
0
$ fq -d mp3 '.headers[0].magic._unknown | ., type, length?' /test.mp3
mp3> .headers[0].magic._unknown | ., type, length?
false
"boolean"
mp3> .headers[0].magic.a = 1
error: expected an object but got: string
mp3> .headers[0].magic[0] = 1
error: expected an array with index 0 but got: string
mp3> .headers[0].magic.a |= empty
error: expected an object but got: string
mp3> .headers[0].magic[0] |= empty
error: expected an array with index 0 but got: string
mp3> .headers[0].magic | setpath(["a"]; 1)
error: expected an object with key "a" but got: string
mp3> .headers[0].magic | setpath([0]; 1)
error: expected an array with index 0 but got: string
mp3> .headers[0].magic | delpaths([["a"]])
error: expected an object with key "a" but got: string
mp3> .headers[0].magic | delpaths([[0]])
error: expected an array with index 0 but got: string
mp3> ^D

39
pkg/interp/testdata/value_t.fqtest.tmpl vendored Normal file
View File

@ -0,0 +1,39 @@
/test.mp3:
$ CMD
PROMPT> EXPR | ., tovalue, type, length?
PROMPT> EXPR[0] | ., type, length?
PROMPT> EXPR[-1000] | ., type, length?
PROMPT> EXPR[1000] | ., type, length?
PROMPT> EXPR[1:3] | ., type, length?
PROMPT> EXPR[0:-1] | ., type, length?
PROMPT> EXPR[-1000:2000] | ., type, length?
PROMPT> EXPR["test"] | ., type, length?
PROMPT> [EXPR[]] | type, length?
PROMPT> EXPR | keys
PROMPT> EXPR | has("a")
PROMPT> EXPR | has(0)
PROMPT> EXPR | type
PROMPT> EXPR | tonumber
PROMPT> EXPR | tostring
PROMPT> EXPR + ""
PROMPT> EXPR + 1
PROMPT> EXPR._start | ., type, length?
PROMPT> EXPR._stop | ., type, length?
PROMPT> EXPR._len | ., type, length?
PROMPT> EXPR._name | ., type, length?
PROMPT> EXPR._symbol | ., type, length?
PROMPT> EXPR._description | ., type, length?
PROMPT> EXPR._path | ., type, length?
PROMPT> EXPR._bits | ., type, length?
PROMPT> EXPR._bytes | ., type, length?
PROMPT> EXPR._error | ., type, length?
PROMPT> EXPR._unknown | ., type, length?
PROMPT> EXPR.a = 1
PROMPT> EXPR[0] = 1
PROMPT> EXPR.a |= empty
PROMPT> EXPR[0] |= empty
PROMPT> EXPR | setpath(["a"]; 1)
PROMPT> EXPR | setpath([0]; 1)
PROMPT> EXPR | delpaths([["a"]])
PROMPT> EXPR | delpaths([[0]])
PROMPT> ^D

View File

@ -0,0 +1,10 @@
#!/bin/sh
sed 's/CMD/fq -i -d mp3 . \/test.mp3/g' <value_t.fqtest.tmpl | sed 's/EXPR/.headers/g' | sed 's/PROMPT/mp3/g' >value_array.fqtest
sed 's/CMD/fq -i -d mp3 . \/test.mp3/g' <value_t.fqtest.tmpl | sed 's/EXPR/.headers[0].flags.unsynchronisation/g' | sed 's/PROMPT/mp3/g' >value_boolean.fqtest
sed 's/CMD/fq -i -d mp3 . \/test.mp3/g' <value_t.fqtest.tmpl | sed 's/EXPR/.headers[0].padding/g' | sed 's/PROMPT/mp3/g' >value_null.fqtest
sed 's/CMD/fq -i -d mp3 . \/test.mp3/g' <value_t.fqtest.tmpl | sed 's/EXPR/.headers[0].version/g' | sed 's/PROMPT/mp3/g' >value_number.fqtest
sed 's/CMD/fq -i -d mp3 . \/test.mp3/g' <value_t.fqtest.tmpl | sed 's/EXPR/.headers[0].flags/g' | sed 's/PROMPT/mp3/g' >value_object.fqtest
sed 's/CMD/fq -i -d mp3 . \/test.mp3/g' <value_t.fqtest.tmpl | sed 's/EXPR/.headers[0].magic/g' | sed 's/PROMPT/mp3/g' >value_string.fqtest
sed "s/CMD/fq -i -n '\"[]\" | json'/g" <value_t.fqtest.tmpl | sed 's/EXPR/(.)/g' | sed 's/PROMPT/json/g' >value_json_array.fqtest
sed "s/CMD/fq -i -n '\"{}\" | json'/g" <value_t.fqtest.tmpl | sed 's/EXPR/(.)/g' | sed 's/PROMPT/json/g' >value_json_object.fqtest

View File

@ -1,41 +0,0 @@
/test.mp3:
# display
> fq -d mp3 'EXPR | ., tovalue, type, length?' /test.mp3
# index
> fq -d mp3 'EXPR[0] | ., type, length?' /test.mp3
> fq -d mp3 'EXPR[-1000] | ., type, length?' /test.mp3
> fq -d mp3 'EXPR[1000] | ., type, length?' /test.mp3
# slice
> fq -d mp3 'EXPR[1:3] | ., type, length?' /test.mp3
> fq -d mp3 'EXPR[0:-1] | ., type, length?' /test.mp3
> fq -d mp3 'EXPR[-1000:2000] | ., type, length?' /test.mp3
# key
> fq -d mp3 'EXPR["test"] | ., type, length?' /test.mp3
# each
> fq -d mp3 '[EXPR[]] | type, length?' /test.mp3
# keys
> fq -d mp3 'EXPR | keys' /test.mp3
# has
> fq -d mp3 'EXPR | has("a")' /test.mp3
> fq -d mp3 'EXPR | has(0)' /test.mp3
# type
> fq -d mp3 'EXPR | type' /test.mp3
# tonumber
> fq -d mp3 'EXPR | tonumber' /test.mp3
# tostring
> fq -d mp3 'EXPR | tostring' /test.mp3
# to gojq
> fq -d mp3 'EXPR + ""' /test.mp3
> fq -d mp3 'EXPR + 1' /test.mp3
# test _keys
> fq -d mp3 'EXPR._start | ., type, length?' /test.mp3
> fq -d mp3 'EXPR._stop | ., type, length?' /test.mp3
> fq -d mp3 'EXPR._len | ., type, length?' /test.mp3
> fq -d mp3 'EXPR._name | ., type, length?' /test.mp3
> fq -d mp3 'EXPR._symbol | ., type, length?' /test.mp3
> fq -d mp3 'EXPR._description | ., type, length?' /test.mp3
> fq -d mp3 'EXPR._path | ., type, length?' /test.mp3
> fq -d mp3 'EXPR._bits | ., type, length?' /test.mp3
> fq -d mp3 'EXPR._bytes | ., type, length?' /test.mp3
> fq -d mp3 'EXPR._error | ., type, length?' /test.mp3
> fq -d mp3 'EXPR._unknown | ., type, length?' /test.mp3

View File

@ -22,6 +22,15 @@ func (err expectedExtkeyError) Error() string {
return "expected a extkey but got: " + err.Key
}
type notUpdateableError struct {
Typ string
Key string
}
func (err notUpdateableError) Error() string {
return fmt.Sprintf("cannot update key %s for %s", err.Key, err.Typ)
}
// TODO: rename
type valueIf interface {
InterpValue
@ -249,6 +258,9 @@ func (v bufferDecodeValue) JQValueSlice(start int, end int) interface{} {
}
return b.String()
}
func (v bufferDecodeValue) JQValueUpdate(key interface{}, u interface{}, delpath bool) interface{} {
return notUpdateableError{Key: fmt.Sprintf("%v", key), Typ: "string"}
}
func (v bufferDecodeValue) JQValueToNumber() interface{} {
s, ok := v.JQValueToString().(string)
if ok {
@ -307,6 +319,9 @@ func (v arrayDecodeValue) JQValueSlice(start int, end int) interface{} {
}
return vs
}
func (v arrayDecodeValue) JQValueUpdate(key interface{}, u interface{}, delpath bool) interface{} {
return notUpdateableError{Key: fmt.Sprintf("%v", key), Typ: "array"}
}
func (v arrayDecodeValue) JQValueEach() interface{} {
props := make([]gojq.PathValue, len(v.Array))
for i, f := range v.Array {
@ -368,6 +383,9 @@ func (v structDecodeValue) JQValueKey(name string) interface{} {
}
return nil
}
func (v structDecodeValue) JQValueUpdate(key interface{}, u interface{}, delpath bool) interface{} {
return notUpdateableError{Key: fmt.Sprintf("%v", key), Typ: "object"}
}
func (v structDecodeValue) JQValueEach() interface{} {
props := make([]gojq.PathValue, len(v.Struct))
for i, f := range v.Struct {