1package pflag 2 3import ( 4 "bytes" 5 "encoding/csv" 6 "strings" 7) 8 9// -- stringSlice Value 10type stringSliceValue struct { 11 value *[]string 12 changed bool 13} 14 15func newStringSliceValue(val []string, p *[]string) *stringSliceValue { 16 ssv := new(stringSliceValue) 17 ssv.value = p 18 *ssv.value = val 19 return ssv 20} 21 22func readAsCSV(val string) ([]string, error) { 23 if val == "" { 24 return []string{}, nil 25 } 26 stringReader := strings.NewReader(val) 27 csvReader := csv.NewReader(stringReader) 28 return csvReader.Read() 29} 30 31func writeAsCSV(vals []string) (string, error) { 32 b := &bytes.Buffer{} 33 w := csv.NewWriter(b) 34 err := w.Write(vals) 35 if err != nil { 36 return "", err 37 } 38 w.Flush() 39 return strings.TrimSuffix(b.String(), "\n"), nil 40} 41 42func (s *stringSliceValue) Set(val string) error { 43 v, err := readAsCSV(val) 44 if err != nil { 45 return err 46 } 47 if !s.changed { 48 *s.value = v 49 } else { 50 *s.value = append(*s.value, v...) 51 } 52 s.changed = true 53 return nil 54} 55 56func (s *stringSliceValue) Type() string { 57 return "stringSlice" 58} 59 60func (s *stringSliceValue) String() string { 61 str, _ := writeAsCSV(*s.value) 62 return "[" + str + "]" 63} 64 65func stringSliceConv(sval string) (interface{}, error) { 66 sval = sval[1 : len(sval)-1] 67 // An empty string would cause a slice with one (empty) string 68 if len(sval) == 0 { 69 return []string{}, nil 70 } 71 return readAsCSV(sval) 72} 73 74// GetStringSlice return the []string value of a flag with the given name 75func (f *FlagSet) GetStringSlice(name string) ([]string, error) { 76 val, err := f.getFlagType(name, "stringSlice", stringSliceConv) 77 if err != nil { 78 return []string{}, err 79 } 80 return val.([]string), nil 81} 82 83// StringSliceVar defines a string flag with specified name, default value, and usage string. 84// The argument p points to a []string variable in which to store the value of the flag. 85func (f *FlagSet) StringSliceVar(p *[]string, name string, value []string, usage string) { 86 f.VarP(newStringSliceValue(value, p), name, "", usage) 87} 88 89// StringSliceVarP is like StringSliceVar, but accepts a shorthand letter that can be used after a single dash. 90func (f *FlagSet) StringSliceVarP(p *[]string, name, shorthand string, value []string, usage string) { 91 f.VarP(newStringSliceValue(value, p), name, shorthand, usage) 92} 93 94// StringSliceVar defines a string flag with specified name, default value, and usage string. 95// The argument p points to a []string variable in which to store the value of the flag. 96func StringSliceVar(p *[]string, name string, value []string, usage string) { 97 CommandLine.VarP(newStringSliceValue(value, p), name, "", usage) 98} 99 100// StringSliceVarP is like StringSliceVar, but accepts a shorthand letter that can be used after a single dash. 101func StringSliceVarP(p *[]string, name, shorthand string, value []string, usage string) { 102 CommandLine.VarP(newStringSliceValue(value, p), name, shorthand, usage) 103} 104 105// StringSlice defines a string flag with specified name, default value, and usage string. 106// The return value is the address of a []string variable that stores the value of the flag. 107func (f *FlagSet) StringSlice(name string, value []string, usage string) *[]string { 108 p := []string{} 109 f.StringSliceVarP(&p, name, "", value, usage) 110 return &p 111} 112 113// StringSliceP is like StringSlice, but accepts a shorthand letter that can be used after a single dash. 114func (f *FlagSet) StringSliceP(name, shorthand string, value []string, usage string) *[]string { 115 p := []string{} 116 f.StringSliceVarP(&p, name, shorthand, value, usage) 117 return &p 118} 119 120// StringSlice defines a string flag with specified name, default value, and usage string. 121// The return value is the address of a []string variable that stores the value of the flag. 122func StringSlice(name string, value []string, usage string) *[]string { 123 return CommandLine.StringSliceP(name, "", value, usage) 124} 125 126// StringSliceP is like StringSlice, but accepts a shorthand letter that can be used after a single dash. 127func StringSliceP(name, shorthand string, value []string, usage string) *[]string { 128 return CommandLine.StringSliceP(name, shorthand, value, usage) 129} 130