From 1903ccaf6404daa17ed466be845beec9e1b4c1a7 Mon Sep 17 00:00:00 2001 From: Bilal Amarni Date: Fri, 27 Sep 2019 18:03:54 +0200 Subject: [PATCH] Add support for float64 --- README.md | 7 ++++--- flag.go | 19 +++++++++++++++++++ flag_test.go | 11 +++++++++++ value.go | 8 ++++++++ value_test.go | 9 +++++++++ 5 files changed, 51 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9d1b355..f6b9294 100644 --- a/README.md +++ b/README.md @@ -123,10 +123,11 @@ Here is a reference of the supported field types: ```go type Options struct { - Name string `flaq:"-n, --name string name of the person to greet"` - Yell bool `flaq:" --yell --yell will set the value to true"` + String string `flaq:"-n, --name string a string eg. --string=world"` + Switch bool `flaq:" --switch --switch will set the value to true"` Bool bool `flaq:" --bool bool --bool, --bool=true or --bool=false"` - Int int `flaq:" --int int an int value"` + Int int `flaq:" --int int an int value eg. --int=100"` + Float64 float64 `flaq:" --float64 float64 a float value eg. --float64=3.14159"` Count int `flaq:"-c, --count count -ccc will set this count value to 3"` Duration time.Duration `flaq:" --duration duration a duration eg. --duration=5min"` } diff --git a/flag.go b/flag.go index 0fbc036..b9cdfab 100644 --- a/flag.go +++ b/flag.go @@ -39,6 +39,11 @@ func Int(ivar *int, long, short, description string) { flags.Int(ivar, long, short, description) } +// Float64 adds a float64 flag with specified long/short form and description. +func Float64(fvar *float64, long, short, description string) { + flags.Float64(fvar, long, short, description) +} + // Count adds a count flag with specified long/short form and description. func Count(cvar *int, long, short, description string) { flags.Count(cvar, long, short, description) @@ -180,6 +185,17 @@ func (f *FlagSet) Int(ivar *int, long, short, description string) { }) } +// Float64 adds a float64 flag with specified long/short form and description. +func (f *FlagSet) Float64(fvar *float64, long, short, description string) { + f.Add(&Flag{ + Long: long, + Short: short, + Description: description, + Value: (*float64Value)(fvar), + Arg: &FlagArg{Name: "float"}, + }) +} + // Count adds a count flag with specified long/short form and description. func (f *FlagSet) Count(cvar *int, long, short, description string) { f.Add(&Flag{ @@ -240,6 +256,9 @@ func (f *FlagSet) Struct(svar interface{}) { case "duration": flag.Value = (*durationValue)(val.(*time.Duration)) flag.Arg = &FlagArg{Name: "duration"} + case "float64": + flag.Value = (*float64Value)(val.(*float64)) + flag.Arg = &FlagArg{Name: "float"} case "int": flag.Value = (*intValue)(val.(*int)) flag.Arg = &FlagArg{Name: "int"} diff --git a/flag_test.go b/flag_test.go index 878b456..f0eccba 100644 --- a/flag_test.go +++ b/flag_test.go @@ -20,6 +20,7 @@ func TestParse(t *testing.T) { car bool count int number int + floatNumber float64 duration time.Duration }{ { @@ -101,6 +102,10 @@ func TestParse(t *testing.T) { args: []string{"--number=50"}, number: 50, }, + { + args: []string{"--float-number=3.14159"}, + floatNumber: 3.14159, + }, { args: []string{"--duration=5m"}, duration: time.Duration(5 * time.Minute), @@ -112,6 +117,7 @@ func TestParse(t *testing.T) { var car, foo, fooBar bool var bar string var count, number int + var floatNumber float64 var duration time.Duration flags := &FlagSet{} @@ -121,6 +127,7 @@ func TestParse(t *testing.T) { flags.Bool(&car, "car", "c", "", false) flags.Count(&count, "count", "", "") flags.Int(&number, "number", "", "") + flags.Float64(&floatNumber, "float-number", "", "") flags.Duration(&duration, "duration", "", "") err := flags.Parse(f.args) @@ -136,6 +143,7 @@ func TestParse(t *testing.T) { assert.Equal(t, f.car, car) assert.Equal(t, f.count, count) assert.Equal(t, f.number, number) + assert.Equal(t, f.floatNumber, floatNumber) assert.Equal(t, f.duration, duration) }) } @@ -188,6 +196,7 @@ func TestParseStruct(t *testing.T) { Yell bool `flaq:" --yell whether to yell or not"` Bool bool `flaq:" --bool bool whether to bool or not"` Int int `flaq:" --int int whether to int or not"` + Float64 float64 `flaq:" --float64 float64 whether to float64 or not"` Count int `flaq:"-c, --count count whether to count or not"` Duration time.Duration `flaq:" --duration duration whether to duration or not"` @@ -202,6 +211,7 @@ func TestParseStruct(t *testing.T) { "--yell", "--bool=true", "--duration=3s", + "--float64=3.14", "--int=100", "-ccc", }) @@ -213,6 +223,7 @@ func TestParseStruct(t *testing.T) { require.Equal(t, 3*time.Second, opts.Duration) require.Equal(t, 100, opts.Int) require.Equal(t, 3, opts.Count) + require.Equal(t, 3.14, opts.Float64) } func TestParseStructFieldTag(t *testing.T) { diff --git a/value.go b/value.go index c2ed54f..8921479 100644 --- a/value.go +++ b/value.go @@ -51,3 +51,11 @@ func (d *durationValue) Set(val string) error { *d = durationValue(v) return err } + +type float64Value float64 + +func (f *float64Value) Set(val string) error { + v, err := strconv.ParseFloat(val, 64) + *f = float64Value(v) + return err +} diff --git a/value_test.go b/value_test.go index 123bc32..3936cbc 100644 --- a/value_test.go +++ b/value_test.go @@ -49,3 +49,12 @@ func TestDurationValue(t *testing.T) { require.NoError(t, val.Set("5s")) require.Equal(t, 5*time.Second, dvar) } + +func TestFloat64Value(t *testing.T) { + var fvar float64 + val := (*float64Value)(&fvar) + + require.Error(t, val.Set("invalid")) + require.NoError(t, val.Set("3.14159265358979323846264338327950288419716939937510")) + require.Equal(t, 3.14159265358979323846264338327950288419716939937510, fvar) +}