mirror of
https://github.com/wader/fq.git
synced 2024-11-23 00:57:15 +03:00
interp: Refactor and use mapstructure
This commit is contained in:
parent
6ce4ba919b
commit
528e6b91ab
3
go.mod
3
go.mod
@ -3,6 +3,9 @@ module github.com/wader/fq
|
|||||||
go 1.17
|
go 1.17
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
// bump: mapstructure /github.com\/mitchellh\/mapstructure v(.*)/ git://github.com/mitchellh/mapstructure|^1
|
||||||
|
// bump: mapstructure command go get -d github.com/mitchellh/mapstructure@v$LATEST && go mod tidy
|
||||||
|
github.com/mitchellh/mapstructure v1.4.2
|
||||||
// bump: go-difflib /github.com\/pmezard\/go-difflib v(.*)/ git://github.com/pmezard/go-difflib|^1
|
// bump: go-difflib /github.com\/pmezard\/go-difflib v(.*)/ git://github.com/pmezard/go-difflib|^1
|
||||||
// bump: go-difflib command go get -d github.com/pmezard/go-difflib@v$LATEST && go mod tidy
|
// bump: go-difflib command go get -d github.com/pmezard/go-difflib@v$LATEST && go mod tidy
|
||||||
github.com/pmezard/go-difflib v1.0.0
|
github.com/pmezard/go-difflib v1.0.0
|
||||||
|
2
go.sum
2
go.sum
@ -9,6 +9,8 @@ github.com/itchyny/timefmt-go v0.1.3 h1:7M3LGVDsqcd0VZH2U+x393obrzZisp7C0uEe921i
|
|||||||
github.com/itchyny/timefmt-go v0.1.3/go.mod h1:0osSSCQSASBJMsIZnhAaF1C2fCBTJZXrnj37mG8/c+A=
|
github.com/itchyny/timefmt-go v0.1.3/go.mod h1:0osSSCQSASBJMsIZnhAaF1C2fCBTJZXrnj37mG8/c+A=
|
||||||
github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||||
|
github.com/mitchellh/mapstructure v1.4.2 h1:6h7AQ0yhTcIsmFmnAwQls75jp2Gzs4iB8W7pjMO+rqo=
|
||||||
|
github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||||
github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354/go.mod h1:KSVJerMDfblTH7p5MZaTt+8zaT2iEk3AkVb9PQdZuE8=
|
github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354/go.mod h1:KSVJerMDfblTH7p5MZaTt+8zaT2iEk3AkVb9PQdZuE8=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
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/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
@ -20,6 +20,7 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/mitchellh/mapstructure"
|
||||||
"github.com/wader/fq/internal/aheadreadseeker"
|
"github.com/wader/fq/internal/aheadreadseeker"
|
||||||
"github.com/wader/fq/internal/ctxreadseeker"
|
"github.com/wader/fq/internal/ctxreadseeker"
|
||||||
"github.com/wader/fq/internal/gojqextra"
|
"github.com/wader/fq/internal/gojqextra"
|
||||||
@ -196,8 +197,12 @@ func makeHashFn(fn func() (hash.Hash, error)) func(c interface{}, a []interface{
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (i *Interp) readline(c interface{}, a []interface{}) interface{} {
|
func (i *Interp) readline(c interface{}, a []interface{}) interface{} {
|
||||||
|
var opts struct {
|
||||||
|
Complete string `mapstructure:"complete"`
|
||||||
|
Timeout float64 `mapstructure:"timeout"`
|
||||||
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
completeFn := ""
|
|
||||||
prompt := ""
|
prompt := ""
|
||||||
|
|
||||||
if len(a) > 0 {
|
if len(a) > 0 {
|
||||||
@ -207,21 +212,22 @@ func (i *Interp) readline(c interface{}, a []interface{}) interface{} {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(a) > 1 {
|
if len(a) > 1 {
|
||||||
completeFn, err = toString(a[1])
|
_ = mapstructure.Decode(a[1], &opts)
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("complete function: %w", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
src, err := i.os.Readline(
|
src, err := i.os.Readline(
|
||||||
prompt,
|
prompt,
|
||||||
func(line string, pos int) (newLine []string, shared int) {
|
func(line string, pos int) (newLine []string, shared int) {
|
||||||
completeCtx, completeCtxCancelFn := context.WithTimeout(i.evalContext.ctx, 1*time.Second)
|
completeCtx := i.evalContext.ctx
|
||||||
defer completeCtxCancelFn()
|
if opts.Timeout > 0 {
|
||||||
|
var completeCtxCancelFn context.CancelFunc
|
||||||
|
completeCtx, completeCtxCancelFn = context.WithTimeout(i.evalContext.ctx, time.Duration(opts.Timeout*float64(time.Second)))
|
||||||
|
defer completeCtxCancelFn()
|
||||||
|
}
|
||||||
|
|
||||||
names, shared, err := func() (newLine []string, shared int, err error) {
|
names, shared, err := func() (newLine []string, shared int, err error) {
|
||||||
vs, err := i.EvalFuncValues(
|
vs, err := i.EvalFuncValues(
|
||||||
completeCtx, CompletionMode, c, completeFn, []interface{}{line, pos}, DiscardCtxWriter{Ctx: completeCtx},
|
completeCtx, c, opts.Complete, []interface{}{line, pos}, DiscardCtxWriter{Ctx: completeCtx},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, pos, err
|
return nil, pos, err
|
||||||
@ -236,32 +242,19 @@ func (i *Interp) readline(c interface{}, a []interface{}) interface{} {
|
|||||||
|
|
||||||
// {abc: 123, abd: 123} | complete(".ab"; 3) will return {prefix: "ab", names: ["abc", "abd"]}
|
// {abc: 123, abd: 123} | complete(".ab"; 3) will return {prefix: "ab", names: ["abc", "abd"]}
|
||||||
|
|
||||||
var names []string
|
var result struct {
|
||||||
var prefix string
|
Names []string `mapstructure:"names"`
|
||||||
cm, ok := v.(map[string]interface{})
|
Prefix string `mapstructure:"prefix"`
|
||||||
if !ok {
|
|
||||||
return nil, pos, fmt.Errorf("%v: complete function return value not an object", cm)
|
|
||||||
}
|
|
||||||
if namesV, ok := cm["names"].([]interface{}); ok {
|
|
||||||
for _, name := range namesV {
|
|
||||||
names = append(names, name.(string))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return nil, pos, fmt.Errorf("%v: names missing in complete return object", cm)
|
|
||||||
}
|
|
||||||
if prefixV, ok := cm["prefix"]; ok {
|
|
||||||
prefix, _ = prefixV.(string)
|
|
||||||
} else {
|
|
||||||
return nil, pos, fmt.Errorf("%v: prefix missing in complete return object", cm)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(names) == 0 {
|
_ = mapstructure.Decode(v, &result)
|
||||||
|
if len(result.Names) == 0 {
|
||||||
return nil, pos, nil
|
return nil, pos, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
sharedLen := len(prefix)
|
sharedLen := len(result.Prefix)
|
||||||
|
|
||||||
return names, sharedLen, nil
|
return result.Names, sharedLen, nil
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// TODO: how to report err?
|
// TODO: how to report err?
|
||||||
@ -296,7 +289,7 @@ func (i *Interp) eval(c interface{}, a []interface{}) gojq.Iter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
iter, err := i.Eval(i.evalContext.ctx, ScriptMode, c, src, filenameHint, i.evalContext.output)
|
iter, err := i.Eval(i.evalContext.ctx, c, src, filenameHint, i.evalContext.output)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return gojq.NewIter(err)
|
return gojq.NewIter(err)
|
||||||
}
|
}
|
||||||
@ -585,33 +578,26 @@ func (i *Interp) _open(c interface{}, a []interface{}) interface{} {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (i *Interp) _decode(c interface{}, a []interface{}) interface{} {
|
func (i *Interp) _decode(c interface{}, a []interface{}) interface{} {
|
||||||
filename := ""
|
var opts struct {
|
||||||
|
Filename string `mapstructure:"filename"`
|
||||||
opts := map[string]interface{}{}
|
Progress string `mapstructure:"_progress"`
|
||||||
if m, ok := a[1].(map[string]interface{}); ok {
|
Remain map[string]interface{} `mapstructure:",remain"`
|
||||||
opts = m
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: structmap
|
|
||||||
var progress string
|
|
||||||
if progressV, ok := opts["_progress"]; ok {
|
|
||||||
progress, _ = progressV.(string)
|
|
||||||
}
|
}
|
||||||
|
_ = mapstructure.Decode(a[1], &opts)
|
||||||
|
|
||||||
// TODO: progress hack
|
// TODO: progress hack
|
||||||
// would be nice to move all progress code into decode but it might be
|
// would be nice to move all progress code into decode but it might be
|
||||||
// tricky to keep track of absolute positions in the underlaying readers
|
// tricky to keep track of absolute positions in the underlaying readers
|
||||||
// when it uses BitBuf slices, maybe only in Pos()?
|
// when it uses BitBuf slices, maybe only in Pos()?
|
||||||
if bbf, ok := c.(*bitBufFile); ok {
|
if bbf, ok := c.(*bitBufFile); ok {
|
||||||
filename = bbf.filename
|
opts.Filename = bbf.filename
|
||||||
|
|
||||||
if progress != "" {
|
if opts.Progress != "" {
|
||||||
evalProgress := func(c interface{}) {
|
evalProgress := func(c interface{}) {
|
||||||
_, _ = i.EvalFuncValues(
|
_, _ = i.EvalFuncValues(
|
||||||
i.evalContext.ctx,
|
i.evalContext.ctx,
|
||||||
CompletionMode,
|
|
||||||
c,
|
c,
|
||||||
progress,
|
opts.Progress,
|
||||||
nil,
|
nil,
|
||||||
DiscardCtxWriter{Ctx: i.evalContext.ctx},
|
DiscardCtxWriter{Ctx: i.evalContext.ctx},
|
||||||
)
|
)
|
||||||
@ -644,8 +630,8 @@ func (i *Interp) _decode(c interface{}, a []interface{}) interface{} {
|
|||||||
|
|
||||||
dv, _, err := decode.Decode(i.evalContext.ctx, bb, decodeFormats,
|
dv, _, err := decode.Decode(i.evalContext.ctx, bb, decodeFormats,
|
||||||
decode.DecodeOptions{
|
decode.DecodeOptions{
|
||||||
Description: filename,
|
Description: opts.Filename,
|
||||||
FormatOptions: opts,
|
FormatOptions: opts.Remain,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
if dv == nil {
|
if dv == nil {
|
||||||
|
@ -17,6 +17,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/mitchellh/mapstructure"
|
||||||
"github.com/wader/fq/format/registry"
|
"github.com/wader/fq/format/registry"
|
||||||
"github.com/wader/fq/internal/ansi"
|
"github.com/wader/fq/internal/ansi"
|
||||||
"github.com/wader/fq/internal/colorjson"
|
"github.com/wader/fq/internal/colorjson"
|
||||||
@ -241,44 +242,6 @@ type loadModule struct {
|
|||||||
func (l loadModule) LoadInitModules() ([]*gojq.Query, error) { return l.init() }
|
func (l loadModule) LoadInitModules() ([]*gojq.Query, error) { return l.init() }
|
||||||
func (l loadModule) LoadModule(name string) (*gojq.Query, error) { return l.load(name) }
|
func (l loadModule) LoadModule(name string) (*gojq.Query, error) { return l.load(name) }
|
||||||
|
|
||||||
func toBool(v interface{}) (bool, error) {
|
|
||||||
switch v := v.(type) {
|
|
||||||
case bool:
|
|
||||||
return v, nil
|
|
||||||
case *big.Int:
|
|
||||||
return v.Int64() != 0, nil
|
|
||||||
case int:
|
|
||||||
return v != 0, nil
|
|
||||||
case float64:
|
|
||||||
return v != 0, nil
|
|
||||||
default:
|
|
||||||
return false, fmt.Errorf("value is not a number")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func toBoolZ(v interface{}) bool {
|
|
||||||
b, _ := toBool(v)
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
func toInt(v interface{}) (int, error) {
|
|
||||||
switch v := v.(type) {
|
|
||||||
case *big.Int:
|
|
||||||
return int(v.Int64()), nil
|
|
||||||
case int:
|
|
||||||
return v, nil
|
|
||||||
case float64:
|
|
||||||
return int(v), nil
|
|
||||||
default:
|
|
||||||
return 0, fmt.Errorf("value is not a number")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func toIntZ(v interface{}) int {
|
|
||||||
n, _ := toInt(v)
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|
||||||
func toString(v interface{}) (string, error) {
|
func toString(v interface{}) (string, error) {
|
||||||
switch v := v.(type) {
|
switch v := v.(type) {
|
||||||
case string:
|
case string:
|
||||||
@ -295,11 +258,6 @@ func toString(v interface{}) (string, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func toStringZ(v interface{}) string {
|
|
||||||
s, _ := toString(v)
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
func toBigInt(v interface{}) (*big.Int, error) {
|
func toBigInt(v interface{}) (*big.Int, error) {
|
||||||
switch v := v.(type) {
|
switch v := v.(type) {
|
||||||
case int:
|
case int:
|
||||||
@ -451,7 +409,6 @@ type evalContext struct {
|
|||||||
// structcheck has problems with embedding https://gitlab.com/opennota/check#known-limitations
|
// structcheck has problems with embedding https://gitlab.com/opennota/check#known-limitations
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
output io.Writer
|
output io.Writer
|
||||||
mode RunMode
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Interp struct {
|
type Interp struct {
|
||||||
@ -500,8 +457,6 @@ func (i *Interp) Stop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (i *Interp) Main(ctx context.Context, output Output, version string) error {
|
func (i *Interp) Main(ctx context.Context, output Output, version string) error {
|
||||||
runMode := ScriptMode
|
|
||||||
|
|
||||||
var args []interface{}
|
var args []interface{}
|
||||||
for _, a := range i.os.Args() {
|
for _, a := range i.os.Args() {
|
||||||
args = append(args, a)
|
args = append(args, a)
|
||||||
@ -512,7 +467,7 @@ func (i *Interp) Main(ctx context.Context, output Output, version string) error
|
|||||||
"version": version,
|
"version": version,
|
||||||
}
|
}
|
||||||
|
|
||||||
iter, err := i.EvalFunc(ctx, runMode, input, "_main", nil, output)
|
iter, err := i.EvalFunc(ctx, input, "_main", nil, output)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintln(i.os.Stderr(), err)
|
fmt.Fprintln(i.os.Stderr(), err)
|
||||||
return err
|
return err
|
||||||
@ -542,7 +497,7 @@ func (i *Interp) Main(ctx context.Context, output Output, version string) error
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Interp) Eval(ctx context.Context, mode RunMode, c interface{}, src string, srcFilename string, output io.Writer) (gojq.Iter, error) {
|
func (i *Interp) Eval(ctx context.Context, c interface{}, src string, srcFilename string, output io.Writer) (gojq.Iter, error) {
|
||||||
gq, err := gojq.Parse(src)
|
gq, err := gojq.Parse(src)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p := queryErrorPosition(src, err)
|
p := queryErrorPosition(src, err)
|
||||||
@ -557,10 +512,7 @@ func (i *Interp) Eval(ctx context.Context, mode RunMode, c interface{}, src stri
|
|||||||
// make copy of interp
|
// make copy of interp
|
||||||
ci := *i
|
ci := *i
|
||||||
ni := &ci
|
ni := &ci
|
||||||
|
ni.evalContext = evalContext{}
|
||||||
ni.evalContext = evalContext{
|
|
||||||
mode: mode,
|
|
||||||
}
|
|
||||||
|
|
||||||
var variableNames []string
|
var variableNames []string
|
||||||
var variableValues []interface{}
|
var variableValues []interface{}
|
||||||
@ -767,7 +719,7 @@ func (i *Interp) Eval(ctx context.Context, mode RunMode, c interface{}, src stri
|
|||||||
return iterWrapper, nil
|
return iterWrapper, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Interp) EvalFunc(ctx context.Context, mode RunMode, c interface{}, name string, args []interface{}, output io.Writer) (gojq.Iter, error) {
|
func (i *Interp) EvalFunc(ctx context.Context, c interface{}, name string, args []interface{}, output io.Writer) (gojq.Iter, error) {
|
||||||
var argsExpr []string
|
var argsExpr []string
|
||||||
for i := range args {
|
for i := range args {
|
||||||
argsExpr = append(argsExpr, fmt.Sprintf("$_args[%d]", i))
|
argsExpr = append(argsExpr, fmt.Sprintf("$_args[%d]", i))
|
||||||
@ -784,15 +736,15 @@ func (i *Interp) EvalFunc(ctx context.Context, mode RunMode, c interface{}, name
|
|||||||
// _args to mark variable as internal and hide it from completion
|
// _args to mark variable as internal and hide it from completion
|
||||||
// {input: ..., args: [...]} | .args as {args: $_args} | .input | name[($_args[0]; ...)]
|
// {input: ..., args: [...]} | .args as {args: $_args} | .input | name[($_args[0]; ...)]
|
||||||
trampolineExpr := fmt.Sprintf(". as {args: $_args} | .input | %s%s", name, argExpr)
|
trampolineExpr := fmt.Sprintf(". as {args: $_args} | .input | %s%s", name, argExpr)
|
||||||
iter, err := i.Eval(ctx, mode, trampolineInput, trampolineExpr, "", output)
|
iter, err := i.Eval(ctx, trampolineInput, trampolineExpr, "", output)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return iter, nil
|
return iter, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Interp) EvalFuncValues(ctx context.Context, mode RunMode, c interface{}, name string, args []interface{}, output io.Writer) ([]interface{}, error) {
|
func (i *Interp) EvalFuncValues(ctx context.Context, c interface{}, name string, args []interface{}, output io.Writer) ([]interface{}, error) {
|
||||||
iter, err := i.EvalFunc(ctx, mode, c, name, args, output)
|
iter, err := i.EvalFunc(ctx, c, name, args, output)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -810,88 +762,29 @@ func (i *Interp) EvalFuncValues(ctx context.Context, mode RunMode, c interface{}
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Options struct {
|
type Options struct {
|
||||||
Depth int
|
Depth int `mapstructure:"depth"`
|
||||||
ArrayTruncate int
|
ArrayTruncate int `mapstructure:"array_truncate"`
|
||||||
Verbose bool
|
Verbose bool `mapstructure:"verbose"`
|
||||||
DecodeProgress bool
|
DecodeProgress bool `mapstructure:"decode_progress"`
|
||||||
Color bool
|
Color bool `mapstructure:"color"`
|
||||||
Colors string
|
Colors string `mapstructure:"colors"`
|
||||||
ByteColors string
|
ByteColors string `mapstructure:"byte_colors"`
|
||||||
Unicode bool
|
Unicode bool `mapstructure:"unicode"`
|
||||||
RawOutput bool
|
RawOutput bool `mapstructure:"raw_output"`
|
||||||
REPL bool
|
REPL bool `mapstructure:"repl"`
|
||||||
RawString bool
|
RawString bool `mapstructure:"raw_string"`
|
||||||
JoinString string
|
JoinString string `mapstructure:"join_string"`
|
||||||
Compact bool
|
Compact bool `mapstructure:"compact"`
|
||||||
BitsFormat string
|
BitsFormat string `mapstructure:"bits_format"`
|
||||||
|
LineBytes int `mapstructure:"line_bytes"`
|
||||||
LineBytes int
|
DisplayBytes int `mapstructure:"display_bytes"`
|
||||||
DisplayBytes int
|
AddrBase int `mapstructure:"addrbase"`
|
||||||
AddrBase int
|
SizeBase int `mapstructure:"sizebase"`
|
||||||
SizeBase int
|
|
||||||
|
|
||||||
Decorator Decorator
|
Decorator Decorator
|
||||||
BitsFormatFn func(bb *bitio.Buffer) (interface{}, error)
|
BitsFormatFn func(bb *bitio.Buffer) (interface{}, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func mapSetOptions(d *Options, m map[string]interface{}) {
|
|
||||||
if v, ok := m["depth"]; ok {
|
|
||||||
d.Depth = num.MaxInt(0, toIntZ(v))
|
|
||||||
}
|
|
||||||
if v, ok := m["array_truncate"]; ok {
|
|
||||||
d.ArrayTruncate = num.MaxInt(0, toIntZ(v))
|
|
||||||
}
|
|
||||||
if v, ok := m["verbose"]; ok {
|
|
||||||
d.Verbose = toBoolZ(v)
|
|
||||||
}
|
|
||||||
if v, ok := m["decode_progress"]; ok {
|
|
||||||
d.DecodeProgress = toBoolZ(v)
|
|
||||||
}
|
|
||||||
if v, ok := m["color"]; ok {
|
|
||||||
d.Color = toBoolZ(v)
|
|
||||||
}
|
|
||||||
if v, ok := m["colors"]; ok {
|
|
||||||
d.Colors = toStringZ(v)
|
|
||||||
}
|
|
||||||
if v, ok := m["byte_colors"]; ok {
|
|
||||||
d.ByteColors = toStringZ(v)
|
|
||||||
}
|
|
||||||
if v, ok := m["unicode"]; ok {
|
|
||||||
d.Unicode = toBoolZ(v)
|
|
||||||
}
|
|
||||||
if v, ok := m["raw_output"]; ok {
|
|
||||||
d.RawOutput = toBoolZ(v)
|
|
||||||
}
|
|
||||||
if v, ok := m["repl"]; ok {
|
|
||||||
d.REPL = toBoolZ(v)
|
|
||||||
}
|
|
||||||
if v, ok := m["raw_string"]; ok {
|
|
||||||
d.RawString = toBoolZ(v)
|
|
||||||
}
|
|
||||||
if v, ok := m["join_string"]; ok {
|
|
||||||
d.JoinString = toStringZ(v)
|
|
||||||
}
|
|
||||||
if v, ok := m["compact"]; ok {
|
|
||||||
d.Compact = toBoolZ(v)
|
|
||||||
}
|
|
||||||
if v, ok := m["bits_format"]; ok {
|
|
||||||
d.BitsFormat = toStringZ(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
if v, ok := m["line_bytes"]; ok {
|
|
||||||
d.LineBytes = num.MaxInt(0, toIntZ(v))
|
|
||||||
}
|
|
||||||
if v, ok := m["display_bytes"]; ok {
|
|
||||||
d.DisplayBytes = num.MaxInt(0, toIntZ(v))
|
|
||||||
}
|
|
||||||
if v, ok := m["addrbase"]; ok {
|
|
||||||
d.AddrBase = num.ClampInt(2, 36, toIntZ(v))
|
|
||||||
}
|
|
||||||
if v, ok := m["sizebase"]; ok {
|
|
||||||
d.SizeBase = num.ClampInt(2, 36, toIntZ(v))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func bitsFormatFnFromOptions(opts Options) func(bb *bitio.Buffer) (interface{}, error) {
|
func bitsFormatFnFromOptions(opts Options) func(bb *bitio.Buffer) (interface{}, error) {
|
||||||
switch opts.BitsFormat {
|
switch opts.BitsFormat {
|
||||||
case "md5":
|
case "md5":
|
||||||
@ -970,7 +863,7 @@ func (i *Interp) variables() map[string]interface{} {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (i *Interp) Options(fnOptsV ...interface{}) (Options, error) {
|
func (i *Interp) Options(fnOptsV ...interface{}) (Options, error) {
|
||||||
vs, err := i.EvalFuncValues(i.evalContext.ctx, ScriptMode, nil, "options", []interface{}{fnOptsV}, DiscardCtxWriter{Ctx: i.evalContext.ctx})
|
vs, err := i.EvalFuncValues(i.evalContext.ctx, nil, "options", []interface{}{fnOptsV}, DiscardCtxWriter{Ctx: i.evalContext.ctx})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Options{}, err
|
return Options{}, err
|
||||||
}
|
}
|
||||||
@ -987,7 +880,13 @@ func (i *Interp) Options(fnOptsV ...interface{}) (Options, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var opts Options
|
var opts Options
|
||||||
mapSetOptions(&opts, m)
|
_ = mapstructure.Decode(m, &opts)
|
||||||
|
opts.Depth = num.MaxInt(0, opts.Depth)
|
||||||
|
opts.ArrayTruncate = num.MaxInt(0, opts.ArrayTruncate)
|
||||||
|
opts.AddrBase = num.ClampInt(2, 36, opts.AddrBase)
|
||||||
|
opts.SizeBase = num.ClampInt(2, 36, opts.SizeBase)
|
||||||
|
opts.LineBytes = num.MaxInt(0, opts.LineBytes)
|
||||||
|
opts.DisplayBytes = num.MaxInt(0, opts.DisplayBytes)
|
||||||
opts.Decorator = decoratorFromOptions(opts)
|
opts.Decorator = decoratorFromOptions(opts)
|
||||||
opts.BitsFormatFn = bitsFormatFnFromOptions(opts)
|
opts.BitsFormatFn = bitsFormatFnFromOptions(opts)
|
||||||
|
|
||||||
|
@ -327,7 +327,7 @@ def _repl($opts): #:: a|(Opts) => @
|
|||||||
def _read_expr:
|
def _read_expr:
|
||||||
# both _prompt and _complete want arrays
|
# both _prompt and _complete want arrays
|
||||||
( . as $c
|
( . as $c
|
||||||
| _readline(_prompt; "_complete")
|
| _readline(_prompt; {complete: "_complete", timeout: 0.5})
|
||||||
| if trim == "" then
|
| if trim == "" then
|
||||||
$c | _read_expr
|
$c | _read_expr
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user