From a0df5f33915247a80a077ec48ed14a8ad5579da4 Mon Sep 17 00:00:00 2001 From: Alex Flint Date: Sat, 13 Jan 2018 14:20:00 -0800 Subject: [PATCH] handle negative values --- parse.go | 18 +++++++++++++++++- parse_test.go | 22 ++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/parse.go b/parse.go index 462aab9..10c6841 100644 --- a/parse.go +++ b/parse.go @@ -345,7 +345,10 @@ func process(specs []*spec, args []string) error { // if we have something like "--foo" then the value is the next argument if value == "" { - if i+1 == len(args) || isFlag(args[i+1]) { + if i+1 == len(args) { + return fmt.Errorf("missing value for %s", arg) + } + if !nextIsNumeric(spec.dest.Type(), args[i+1]) && isFlag(args[i+1]) { return fmt.Errorf("missing value for %s", arg) } value = args[i+1] @@ -387,6 +390,19 @@ func process(specs []*spec, args []string) error { return nil } +func nextIsNumeric(t reflect.Type, s string) bool { + switch t.Kind() { + case reflect.Ptr: + return nextIsNumeric(t.Elem(), s) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Float32, reflect.Float64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + v := reflect.New(t) + err := scalar.ParseValue(v, s) + return err == nil + default: + return false + } +} + // isFlag returns true if a token is a flag such as "-v" or "--user" but not "-" or "--" func isFlag(s string) bool { return strings.HasPrefix(s, "-") && strings.TrimLeft(s, "-") != "" diff --git a/parse_test.go b/parse_test.go index 701b105..925a23e 100644 --- a/parse_test.go +++ b/parse_test.go @@ -67,6 +67,28 @@ func TestInt(t *testing.T) { assert.EqualValues(t, 8, *args.Ptr) } +func TestNegativeInt(t *testing.T) { + var args struct { + Foo int + } + err := parse("-foo -100", &args) + require.NoError(t, err) + assert.EqualValues(t, args.Foo, -100) +} + +func TestNegativeIntAndFloatAndTricks(t *testing.T) { + var args struct { + Foo int + Bar float64 + N int `arg:"--100"` + } + err := parse("-foo -100 -bar -60.14 -100 -100", &args) + require.NoError(t, err) + assert.EqualValues(t, args.Foo, -100) + assert.EqualValues(t, args.Bar, -60.14) + assert.EqualValues(t, args.N, -100) +} + func TestUint(t *testing.T) { var args struct { Foo uint