Skip to content

Commit

Permalink
Add WrapCSV, handle nil flag.Values
Browse files Browse the repository at this point in the history
  • Loading branch information
sgreben committed May 19, 2018
1 parent 114af1c commit 712df2a
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 2 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ Here's a compact overview:
| [URL](https://godoc.org/github.com/sgreben/flagvar#URL) | https://github.com | *url.URL |
| [URLs](https://godoc.org/github.com/sgreben/flagvar#URLs) | https://github.com | []*url.URL |
| [Wrap](https://godoc.org/github.com/sgreben/flagvar#Wrap) | | |
| [WrapCSV](https://godoc.org/github.com/sgreben/flagvar#WrapCSV) | | |
| [WrapFunc](https://godoc.org/github.com/sgreben/flagvar#WrapFunc) | | |
| [WrapPointer](https://godoc.org/github.com/sgreben/flagvar#WrapPointer) | | |

Expand Down
5 changes: 4 additions & 1 deletion alternative.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,8 @@ func (fv *Alternative) String() string {
if fv.EitherOk {
return fv.Either.String()
}
return fv.Or.String()
if fv.Or != nil {
return fv.Or.String()
}
return ""
}
57 changes: 56 additions & 1 deletion wrap.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package flagvar

import "flag"
import (
"flag"
"strings"
)

// WrapPointer wraps a pointer to a `flag.Value`
// This can be used to switch between different argument parsers.
Expand All @@ -14,6 +17,9 @@ func (fv *WrapPointer) Set(v string) error {
}

func (fv WrapPointer) String() string {
if fv.Value == nil || (*fv.Value) == nil {
return ""
}
return (*fv.Value).String()
}

Expand All @@ -27,6 +33,9 @@ func (fv WrapFunc) Set(v string) error {
}

func (fv WrapFunc) String() string {
if fv == nil {
return ""
}
return fv().String()
}

Expand All @@ -46,5 +55,51 @@ func (fv *Wrap) Set(v string) error {
}

func (fv *Wrap) String() string {
if fv.Value == nil {
return ""
}
return fv.Value.String()
}

// WrapCSV wraps a `flag.Value` and calls `UpdatedOne` after each single value and `UpdatedAll` after each CSV batch.
// The `Separator` field is used instead of the comma when set.
type WrapCSV struct {
Value flag.Value
Separator string
UpdatedOne func()
UpdatedAll func()
StringFunc func() string
}

// Set is flag.Value.Set
func (fv *WrapCSV) Set(v string) error {
separator := fv.Separator
if separator == "" {
separator = ","
}
parts := strings.Split(v, separator)
for _, part := range parts {
part = strings.TrimSpace(part)
err := fv.Value.Set(part)
if err != nil {
return err
}
if fv.UpdatedOne != nil {
fv.UpdatedOne()
}
}
if fv.UpdatedAll != nil {
fv.UpdatedAll()
}
return nil
}

func (fv *WrapCSV) String() string {
if fv.StringFunc != nil {
return fv.StringFunc()
}
if fv.Value == nil {
return ""
}
return fv.Value.String()
}
86 changes: 86 additions & 0 deletions wrap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ package flagvar_test

import (
"flag"
"fmt"
"reflect"
"sort"
"strings"
"testing"

"github.com/sgreben/flagvar"
Expand Down Expand Up @@ -64,3 +67,86 @@ func TestWrap(t *testing.T) {
t.Fail()
}
}

func TestWrapCSV(t *testing.T) {
sv := &flagvar.Strings{}
fv := flagvar.WrapCSV{Value: sv}
var fs flag.FlagSet
fs.Var(&fv, "wrap-csv", "")

err := fs.Parse([]string{"-wrap-csv", "abc,def", "-wrap-csv", "xyz"})
if err != nil {
t.Fail()
}
if !reflect.DeepEqual(sv.Values, []string{"abc", "def", "xyz"}) {
t.Fail()
}
}

func TestWrapCSVFail(t *testing.T) {
sv := &flagvar.IP{}
fv := flagvar.WrapCSV{Value: sv}
var fs flag.FlagSet
fs.Var(&fv, "wrap-csv", "")

err := fs.Parse([]string{"-wrap-csv", "127.0.0.1,def"})
if err == nil {
t.Fail()
}
}

func TestWrapCSVSeparator(t *testing.T) {
sv := &flagvar.Strings{}
fv := flagvar.WrapCSV{
Value: sv,
Separator: ";",
}
var fs flag.FlagSet
fs.Var(&fv, "wrap-csv", "")

err := fs.Parse([]string{"-wrap-csv", "abc;def", "-wrap-csv", "xyz"})
if err != nil {
t.Fail()
}
if !reflect.DeepEqual(sv.Values, []string{"abc", "def", "xyz"}) {
t.Fail()
}
}

func TestWrapCSVUpdated(t *testing.T) {
sv := &flagvar.Assignment{}
current := map[string]string{}
final := map[string]string{}
fv := flagvar.WrapCSV{
Value: sv,
UpdatedOne: func() {
current[sv.Value.Key] = sv.Value.Value
},
UpdatedAll: func() {
final = current
current = map[string]string{}
},
StringFunc: func() string {
var out []string
for k, v := range final {
out = append(out, fmt.Sprintf("%s=%s", k, v))
}
sort.Strings(out)
return strings.Join(out, ",")
},
}
var fs flag.FlagSet
fs.Var(&fv, "wrap-csv", "")

err := fs.Parse([]string{"-wrap-csv", "xyz=abc", "-wrap-csv", "abc=def,def=xyz"})
if err != nil {
t.Fail()
}
fmt.Println(final)
if !reflect.DeepEqual(final, map[string]string{"abc": "def", "def": "xyz"}) {
t.Fail()
}
if !reflect.DeepEqual(fv.String(), `abc=def,def=xyz`) {
t.Fail()
}
}

0 comments on commit 712df2a

Please sign in to comment.