mirror of
https://github.com/wader/fq.git
synced 2024-11-23 00:57:15 +03:00
interp,repl: Improved eval and output interrupt
repl now rewrites query to do implicit display inside the sub eval. This makes it possible to interrupt eval and output in a better and faster way. Make JSON encoder fail early on errors. Add more interrupt tests.
This commit is contained in:
parent
dd52e85411
commit
41551de331
@ -205,6 +205,10 @@ func (e *Encoder) encodeArray(vs []interface{}) {
|
||||
e.writeByte('[', e.colors.Array)
|
||||
e.depth += e.indent
|
||||
for i, v := range vs {
|
||||
if e.wErr != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if i > 0 {
|
||||
e.writeByte(',', e.colors.Array)
|
||||
}
|
||||
@ -237,6 +241,10 @@ func (e *Encoder) encodeMap(vs map[string]interface{}) {
|
||||
return kvs[i].key < kvs[j].key
|
||||
})
|
||||
for i, kv := range kvs {
|
||||
if e.wErr != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if i > 0 {
|
||||
e.writeByte(',', e.colors.Object)
|
||||
}
|
||||
|
@ -31,6 +31,13 @@ expect "123"
|
||||
send "\x03"
|
||||
expect "mp3> "
|
||||
|
||||
# test interrupt multiple outputs implicit display
|
||||
send "range(100000)\n"
|
||||
expect "123"
|
||||
# ctrl-c
|
||||
send "\x03"
|
||||
expect "mp3> "
|
||||
|
||||
# test interrupt big json output
|
||||
send "\[range(100000)\] | d\n"
|
||||
expect "123"
|
||||
@ -38,6 +45,13 @@ expect "123"
|
||||
send "\x03"
|
||||
expect "mp3> "
|
||||
|
||||
# test interrupt big json output implicit display
|
||||
send "\[range(100000)\]\n"
|
||||
expect "123"
|
||||
# ctrl-c
|
||||
send "\x03"
|
||||
expect "mp3> "
|
||||
|
||||
# test exit
|
||||
# ctrl-d
|
||||
send "\x04"
|
||||
|
@ -17,6 +17,13 @@ def _eval_error_function_not_defined($name; $args):
|
||||
"function not defined: \($name)/\($args | length)"
|
||||
);
|
||||
|
||||
# if catch_query . -> try (.) catch .catch_query
|
||||
# if input_query . -> .input_query | .
|
||||
# if ... | <.slurp.> -> .slurp({slurp: "<slurp>", slurp_args: [arg query ast], orig: orig query ast, rewrite: rewritten query})
|
||||
# else if .output_query -> . | .output_query
|
||||
#
|
||||
# ex ... | slurp -> <slurp>({...})
|
||||
# ex no slurp: . -> try (.input_query | . | .output_query) catch .catch_query
|
||||
def _eval_query_rewrite($opts):
|
||||
_query_fromtostring(
|
||||
( . as $orig_query
|
||||
@ -35,10 +42,9 @@ def _eval_query_rewrite($opts):
|
||||
# try (1+1) catch vs try 1 + 1 catch
|
||||
_query_try(. | _query_query; $opts.catch_query)
|
||||
end
|
||||
| _query_pipe(
|
||||
$opts.input_query // _query_ident;
|
||||
.
|
||||
)
|
||||
| if $opts.input_query then
|
||||
_query_pipe($opts.input_query; .)
|
||||
end
|
||||
| if $slurp then
|
||||
_query_func(
|
||||
$slurp;
|
||||
@ -61,6 +67,8 @@ def _eval_query_rewrite($opts):
|
||||
)
|
||||
]
|
||||
)
|
||||
elif $opts.output_query then
|
||||
_query_pipe(.; $opts.output_query)
|
||||
end
|
||||
)
|
||||
);
|
||||
|
@ -194,5 +194,6 @@ def _help($arg0; $topic):
|
||||
( _repl_slurp_eval($query.rewrite) as $outputs
|
||||
| "value help"
|
||||
, $outputs
|
||||
| display
|
||||
)
|
||||
end;
|
||||
|
@ -918,6 +918,8 @@ func (i *Interp) Eval(ctx context.Context, c interface{}, expr string, opts Eval
|
||||
// gojq ctx cancel will not return ok=false, just cancelled error
|
||||
if !ok {
|
||||
runCtxCancelFn()
|
||||
} else if _, ok := v.(error); ok {
|
||||
runCtxCancelFn()
|
||||
}
|
||||
return v, ok
|
||||
})
|
||||
|
@ -211,18 +211,26 @@ def _repl_on_compile_error:
|
||||
end
|
||||
| println
|
||||
);
|
||||
def _repl_eval($expr; on_error; on_compile_error; $slurps):
|
||||
def _repl_display:
|
||||
display(_display_default_opts);
|
||||
def _repl_eval($expr; on_error; on_compile_error):
|
||||
eval(
|
||||
$expr;
|
||||
{ slurps: $slurps,
|
||||
{ slurps:
|
||||
{ repl: "_repl_slurp",
|
||||
help: "_help_slurp",
|
||||
slurp: "_slurp"
|
||||
},
|
||||
# input to repl is always array of values to iterate
|
||||
input_query: (_query_ident | _query_iter), # .[]
|
||||
catch_query: _query_func("_repl_on_expr_error")
|
||||
# each input should be evaluted separatel like with cli, so catch and just print errors
|
||||
catch_query: _query_func("_repl_on_expr_error"),
|
||||
# run display in sub eval so it can be interrupted
|
||||
output_query: _query_func("_repl_display")
|
||||
};
|
||||
on_error;
|
||||
on_compile_error
|
||||
);
|
||||
def _repl_eval($expr; on_error; on_compile_error):
|
||||
_repl_eval($expr; on_error; on_compile_error; null);
|
||||
|
||||
# run read-eval-print-loop
|
||||
# input is array of inputs to iterate
|
||||
@ -242,17 +250,10 @@ def _repl($opts):
|
||||
);
|
||||
def _repl_loop:
|
||||
try
|
||||
( _display_default_opts as $default_opts
|
||||
| _repl_eval(
|
||||
_read_expr;
|
||||
_repl_on_error;
|
||||
_repl_on_compile_error;
|
||||
{ repl: "_repl_slurp",
|
||||
help: "_help_slurp",
|
||||
slurp: "_slurp"
|
||||
}
|
||||
)
|
||||
| display($default_opts)
|
||||
_repl_eval(
|
||||
_read_expr;
|
||||
_repl_on_error;
|
||||
_repl_on_compile_error
|
||||
)
|
||||
catch
|
||||
if . == "interrupt" then empty
|
||||
|
Loading…
Reference in New Issue
Block a user