Skip to content

Commit

Permalink
interp: Make tovalue output behave as jq value
Browse files Browse the repository at this point in the history
Now ex "tovalue | .some.thing" on a decode value will make some.thing be jq value
instead of a decode value which woud be displayed as a decode treee, seems confusing.

I think this is more intuetive and make more sense.
  • Loading branch information
wader committed Apr 29, 2023
1 parent 6194b87 commit ee66fec
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 23 deletions.
27 changes: 16 additions & 11 deletions internal/gojqex/totype.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,17 @@ func IsNull(x any) bool {
}

func ToGoJQValue(v any) (any, bool) {
return ToGoJQValueFn(v, func(v any) (any, bool) {
switch v := v.(type) {
case gojq.JQValue:
return v.JQValueToGoJQ(), true
default:
return nil, false
}
})
}

func ToGoJQValueFn(v any, valueFn func(v any) (any, bool)) (any, bool) {
switch vv := v.(type) {
case nil:
return vv, true
Expand Down Expand Up @@ -51,25 +62,16 @@ func ToGoJQValue(v any) (any, bool) {
if vv >= math.MinInt && vv <= math.MaxInt {
return int(vv), true
}
return vv, true
} else if vv.IsUint64() {
vv := vv.Uint64()
if vv <= math.MaxInt {
return int(vv), true
}
return vv, true
}
return vv, true
case string:
return vv, true
case []byte:
return string(vv), true
case gojq.JQValue:
return ToGoJQValue(vv.JQValueToGoJQ())
case []any:
vvs := make([]any, len(vv))
for i, v := range vv {
v, ok := ToGoJQValue(v)
v, ok := ToGoJQValueFn(v, valueFn)
if !ok {
return nil, false
}
Expand All @@ -79,14 +81,17 @@ func ToGoJQValue(v any) (any, bool) {
case map[string]any:
vvs := make(map[string]any, len(vv))
for k, v := range vv {
v, ok := ToGoJQValue(v)
v, ok := ToGoJQValueFn(v, valueFn)
if !ok {
return nil, false
}
vvs[k] = v
}
return vvs, true
default:
if nv, ok := valueFn(vv); ok {
return ToGoJQValueFn(nv, valueFn)
}
return nil, false
}
}
26 changes: 15 additions & 11 deletions pkg/interp/decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,19 +305,23 @@ func valueHas(key any, a func(name string) any, b func(key any) any) any {
return b(key)
}

// optsFn is a function as toValue is used by tovalue/0 so needs to be fast
// TODO: make more efficient somehow? shallow values but might be hard
// when things like tovalue.key should behave like a jq value and not a decode value etc
func toValue(optsFn func() Options, v any) any {
switch v := v.(type) {
case JQValueEx:
if optsFn == nil {
return v.JQValueToGoJQ()
nv, _ := gojqex.ToGoJQValueFn(v, func(v any) (any, bool) {
switch v := v.(type) {
case JQValueEx:
if optsFn == nil {
return v.JQValueToGoJQ(), true
}
return v.JQValueToGoJQEx(optsFn), true
case gojq.JQValue:
return v.JQValueToGoJQ(), true
default:
return v, true
}
return v.JQValueToGoJQEx(optsFn)
case gojq.JQValue:
return v.JQValueToGoJQ()
default:
return v
}
})
return nv
}

type decodeValueKind int
Expand Down
3 changes: 2 additions & 1 deletion pkg/interp/interp.jq
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ def display($opts):
( . as $c
| options($opts) as $opts
| try _todisplay catch $c
| if ($opts.value_output | not) and _can_display then _display($opts)
| if $opts.value_output then tovalue end
| if _can_display then _display($opts)
else
( if _is_string and $opts.raw_string then print
else _print_color_json($opts)
Expand Down
4 changes: 4 additions & 0 deletions pkg/interp/testdata/tovalue.fqtest
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
# TODO: use test format
$ fq -i . test.mp3
mp3> .headers[0] | tovalue.header.magic
"ID3"
mp3> ^D
$ fq -i
null> "aaa" | mp3_frame | .gap0 | tovalue, tovalue({sizebase: 2})
"aaa"
Expand Down
4 changes: 4 additions & 0 deletions pkg/interp/testdata/value_output.fqtest
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,7 @@ ID3
"unused": 0
}
35
$ fq -o bits_format=base64 -V '.frames[0].audio_data' test.mp3
"AAAAAAA="
$ fq -o bits_format=base64 -Vr '.frames[0].audio_data' test.mp3
AAAAAAA=

0 comments on commit ee66fec

Please sign in to comment.