string_slice.go 4.0 KB

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