diff options
| author | Grégoire Duchêne <gduchene@awhk.org> | 2022-06-26 16:26:31 +0100 |
|---|---|---|
| committer | Grégoire Duchêne <gduchene@awhk.org> | 2022-06-26 16:26:31 +0100 |
| commit | d8366888efe8ef5626735ba5bb3774f075d7132c (patch) | |
| tree | f4aa914a04705216662bb160e3f80131b09bb469 | |
| parent | 37faccb93a8e0a6c7beb46259e09fe556cd3b1ea (diff) | |
Simplify the flag helper functionsv0.1.0
| -rw-r--r-- | flag.go | 64 | ||||
| -rw-r--r-- | flag_test.go | 58 |
2 files changed, 58 insertions, 64 deletions
@@ -9,37 +9,39 @@ import ( "time" ) -func FlagVar[T any](fs *flag.FlagSet, name, usage string, parse ParseFunc[T]) *T { - v := &flagValue[T]{Parse: parse, Value: new(T)} - fs.Var(v, name, usage) - return v.Value +// FlagT works like other flag.FlagSet methods, except it is generic. +// The passed ParseFunc will be used to parse raw arguments into a +// useful T value. A valid *T is returned for use by the caller. +func FlagT[T any](fs *flag.FlagSet, name string, value T, usage string, parse ParseFunc[T]) *T { + p := new(T) + FlagTVar(fs, p, name, value, usage, parse) + return p } -func FlagVarDef[T any](fs *flag.FlagSet, name, usage string, parse ParseFunc[T], def T) *T { - val := def - FlagVarPtr(fs, name, usage, parse, &val) - return &val +// FlagTVar works like FlagT, except it is up to the caller to supply a +// valid *T. +func FlagTVar[T any](fs *flag.FlagSet, p *T, name string, value T, usage string, parse ParseFunc[T]) { + *p = value + fs.Var(&flagValue[T]{Parse: parse, Value: p}, name, usage) } -func FlagVarPtr[T any](fs *flag.FlagSet, name, usage string, parse ParseFunc[T], val *T) { - fs.Var(&flagValue[T]{Parse: parse, Value: val}, name, usage) +// FlagTSlice works like FlagT, except slices are created; flags created +// that way can therefore be repeated. A valid *[]T is returned for use +// by the caller. +func FlagTSlice[T any](fs *flag.FlagSet, name string, values []T, usage string, parse ParseFunc[T]) *[]T { + p := new([]T) + FlagTSliceVar(fs, p, name, values, usage, parse) + return p } -func FlagVarSlice[T any](fs *flag.FlagSet, name, usage string, parse ParseFunc[T]) *[]T { - v := &flagValueSlice[T]{Parse: parse, Values: new([]T)} - fs.Var(v, name, usage) - return v.Values -} - -func FlagVarSliceDef[T any](fs *flag.FlagSet, name, usage string, parse ParseFunc[T], def []T) *[]T { - vals := make([]T, len(def)) - copy(vals, def) - FlagVarSlicePtr(fs, name, usage, parse, &vals) - return &vals -} - -func FlagVarSlicePtr[T any](fs *flag.FlagSet, name, usage string, parse ParseFunc[T], vals *[]T) { - fs.Var(&flagValueSlice[T]{Parse: parse, Values: vals}, name, usage) +// FlagTSliceVar works like FlagTSlice, except it is up to the caller to +// supply a valid *[]T. +func FlagTSliceVar[T any](fs *flag.FlagSet, p *[]T, name string, values []T, usage string, parse ParseFunc[T]) { + if values != nil { + *p = make([]T, len(values)) + copy(*p, values) + } + fs.Var(&flagValueSlice[T]{Parse: parse, Values: p}, name, usage) } // ParseString returns the string passed with no error set. @@ -73,7 +75,11 @@ func (f *flagValue[T]) Set(s string) error { } func (f *flagValue[T]) String() string { - return fmt.Sprintf("%v", f.Value) + if f.Value == nil { + var zero T + return fmt.Sprintf("%v", zero) + } + return fmt.Sprintf("%v", *f.Value) } type flagValueSlice[T any] struct { @@ -100,5 +106,9 @@ func (f *flagValueSlice[T]) Set(s string) error { } func (f *flagValueSlice[T]) String() string { - return fmt.Sprintf("%v", f.Values) + if f.Values == nil { + var zero []T + return fmt.Sprintf("%v", zero) + } + return fmt.Sprintf("%v", *f.Values) } diff --git a/flag_test.go b/flag_test.go index a4da69b..1492e7a 100644 --- a/flag_test.go +++ b/flag_test.go @@ -11,60 +11,44 @@ import ( "go.awhk.org/core" ) -func TestFlagVar(s *testing.T) { +func TestFlagT(s *testing.T) { t := core.T{T: s} - fs := flag.NewFlagSet("", flag.ContinueOnError) - fl := core.FlagVar(fs, "test", "", strconv.ParseBool) - t.AssertErrorIs(nil, fs.Parse([]string{"-test=true"})) - t.AssertEqual(true, *fl) -} - -func TestFlagVarDef(s *testing.T) { - t := core.T{T: s} - - fs := flag.NewFlagSet("", flag.ContinueOnError) - fl := core.FlagVarDef(fs, "test", "", strconv.Atoi, 42) + fs := flag.NewFlagSet("", flag.PanicOnError) + fl := core.FlagT(fs, "test", 42, "", strconv.Atoi) t.AssertEqual(42, *fl) - t.AssertErrorIs(nil, fs.Parse([]string{"-test=1"})) - t.AssertEqual(1, *fl) + t.AssertErrorIs(nil, fs.Parse([]string{"-test=84"})) + t.AssertEqual(84, *fl) } -func TestFlagVarPtr(s *testing.T) { +func TestFlagTVar(s *testing.T) { t := core.T{T: s} - fs := flag.NewFlagSet("", flag.ContinueOnError) - fl := false - core.FlagVarPtr(fs, "test", "", strconv.ParseBool, &fl) - t.AssertErrorIs(nil, fs.Parse([]string{"-test=true"})) - t.AssertEqual(true, fl) + fs := flag.NewFlagSet("", flag.PanicOnError) + var fl int + core.FlagTVar(fs, &fl, "test", 42, "", strconv.Atoi) + t.AssertEqual(42, fl) + t.AssertErrorIs(nil, fs.Parse([]string{"-test=84"})) + t.AssertEqual(84, fl) } -func TestFlagVarSlice(s *testing.T) { +func TestFlagTSlice(s *testing.T) { t := core.T{T: s} - fs := flag.NewFlagSet("", flag.ContinueOnError) - fl := core.FlagVarSlice(fs, "test", "", strconv.Atoi) + fs := flag.NewFlagSet("", flag.PanicOnError) + fl := core.FlagTSlice(fs, "test", []int{42}, "", strconv.Atoi) + t.AssertEqual([]int{42}, *fl) t.AssertErrorIs(nil, fs.Parse([]string{"-test=1", "-test=2", "-test=42"})) t.AssertEqual([]int{1, 2, 42}, *fl) } -func TestFlagVarSliceDef(s *testing.T) { - t := core.T{T: s} - - fs := flag.NewFlagSet("", flag.ContinueOnError) - fl := core.FlagVarSliceDef(fs, "test", "", strconv.Atoi, []int{42}) - t.AssertEqual([]int{42}, *fl) - t.AssertErrorIs(nil, fs.Parse([]string{"-test=1", "-test=2"})) - t.AssertEqual([]int{1, 2}, *fl) -} - -func TestFlagVarSlicePtr(s *testing.T) { +func TestFlagTSliceVar(s *testing.T) { t := core.T{T: s} - fs := flag.NewFlagSet("", flag.ContinueOnError) - fl := []int{} - core.FlagVarSlicePtr(fs, "test", "", strconv.Atoi, &fl) + fs := flag.NewFlagSet("", flag.PanicOnError) + var fl []int + core.FlagTSliceVar(fs, &fl, "test", []int{42}, "", strconv.Atoi) + t.AssertEqual([]int{42}, fl) t.AssertErrorIs(nil, fs.Parse([]string{"-test=1", "-test=2", "-test=42"})) t.AssertEqual([]int{1, 2, 42}, fl) } |
