bool_slice.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. package pflag
  2. import (
  3. "io"
  4. "strconv"
  5. "strings"
  6. )
  7. // -- boolSlice Value
  8. type boolSliceValue struct {
  9. value *[]bool
  10. changed bool
  11. }
  12. func newBoolSliceValue(val []bool, p *[]bool) *boolSliceValue {
  13. bsv := new(boolSliceValue)
  14. bsv.value = p
  15. *bsv.value = val
  16. return bsv
  17. }
  18. // Set converts, and assigns, the comma-separated boolean argument string representation as the []bool value of this flag.
  19. // If Set is called on a flag that already has a []bool assigned, the newly converted values will be appended.
  20. func (s *boolSliceValue) Set(val string) error {
  21. // remove all quote characters
  22. rmQuote := strings.NewReplacer(`"`, "", `'`, "", "`", "")
  23. // read flag arguments with CSV parser
  24. boolStrSlice, err := readAsCSV(rmQuote.Replace(val))
  25. if err != nil && err != io.EOF {
  26. return err
  27. }
  28. // parse boolean values into slice
  29. out := make([]bool, 0, len(boolStrSlice))
  30. for _, boolStr := range boolStrSlice {
  31. b, err := strconv.ParseBool(strings.TrimSpace(boolStr))
  32. if err != nil {
  33. return err
  34. }
  35. out = append(out, b)
  36. }
  37. if !s.changed {
  38. *s.value = out
  39. } else {
  40. *s.value = append(*s.value, out...)
  41. }
  42. s.changed = true
  43. return nil
  44. }
  45. // Type returns a string that uniquely represents this flag's type.
  46. func (s *boolSliceValue) Type() string {
  47. return "boolSlice"
  48. }
  49. // String defines a "native" format for this boolean slice flag value.
  50. func (s *boolSliceValue) String() string {
  51. boolStrSlice := make([]string, len(*s.value))
  52. for i, b := range *s.value {
  53. boolStrSlice[i] = strconv.FormatBool(b)
  54. }
  55. out, _ := writeAsCSV(boolStrSlice)
  56. return "[" + out + "]"
  57. }
  58. func (s *boolSliceValue) fromString(val string) (bool, error) {
  59. return strconv.ParseBool(val)
  60. }
  61. func (s *boolSliceValue) toString(val bool) string {
  62. return strconv.FormatBool(val)
  63. }
  64. func (s *boolSliceValue) Append(val string) error {
  65. i, err := s.fromString(val)
  66. if err != nil {
  67. return err
  68. }
  69. *s.value = append(*s.value, i)
  70. return nil
  71. }
  72. func (s *boolSliceValue) Replace(val []string) error {
  73. out := make([]bool, len(val))
  74. for i, d := range val {
  75. var err error
  76. out[i], err = s.fromString(d)
  77. if err != nil {
  78. return err
  79. }
  80. }
  81. *s.value = out
  82. return nil
  83. }
  84. func (s *boolSliceValue) GetSlice() []string {
  85. out := make([]string, len(*s.value))
  86. for i, d := range *s.value {
  87. out[i] = s.toString(d)
  88. }
  89. return out
  90. }
  91. func boolSliceConv(val string) (interface{}, error) {
  92. val = strings.Trim(val, "[]")
  93. // Empty string would cause a slice with one (empty) entry
  94. if len(val) == 0 {
  95. return []bool{}, nil
  96. }
  97. ss := strings.Split(val, ",")
  98. out := make([]bool, len(ss))
  99. for i, t := range ss {
  100. var err error
  101. out[i], err = strconv.ParseBool(t)
  102. if err != nil {
  103. return nil, err
  104. }
  105. }
  106. return out, nil
  107. }
  108. // GetBoolSlice returns the []bool value of a flag with the given name.
  109. func (f *FlagSet) GetBoolSlice(name string) ([]bool, error) {
  110. val, err := f.getFlagType(name, "boolSlice", boolSliceConv)
  111. if err != nil {
  112. return []bool{}, err
  113. }
  114. return val.([]bool), nil
  115. }
  116. // BoolSliceVar defines a boolSlice flag with specified name, default value, and usage string.
  117. // The argument p points to a []bool variable in which to store the value of the flag.
  118. func (f *FlagSet) BoolSliceVar(p *[]bool, name string, value []bool, usage string) {
  119. f.VarP(newBoolSliceValue(value, p), name, "", usage)
  120. }
  121. // BoolSliceVarP is like BoolSliceVar, but accepts a shorthand letter that can be used after a single dash.
  122. func (f *FlagSet) BoolSliceVarP(p *[]bool, name, shorthand string, value []bool, usage string) {
  123. f.VarP(newBoolSliceValue(value, p), name, shorthand, usage)
  124. }
  125. // BoolSliceVar defines a []bool flag with specified name, default value, and usage string.
  126. // The argument p points to a []bool variable in which to store the value of the flag.
  127. func BoolSliceVar(p *[]bool, name string, value []bool, usage string) {
  128. CommandLine.VarP(newBoolSliceValue(value, p), name, "", usage)
  129. }
  130. // BoolSliceVarP is like BoolSliceVar, but accepts a shorthand letter that can be used after a single dash.
  131. func BoolSliceVarP(p *[]bool, name, shorthand string, value []bool, usage string) {
  132. CommandLine.VarP(newBoolSliceValue(value, p), name, shorthand, usage)
  133. }
  134. // BoolSlice defines a []bool flag with specified name, default value, and usage string.
  135. // The return value is the address of a []bool variable that stores the value of the flag.
  136. func (f *FlagSet) BoolSlice(name string, value []bool, usage string) *[]bool {
  137. p := []bool{}
  138. f.BoolSliceVarP(&p, name, "", value, usage)
  139. return &p
  140. }
  141. // BoolSliceP is like BoolSlice, but accepts a shorthand letter that can be used after a single dash.
  142. func (f *FlagSet) BoolSliceP(name, shorthand string, value []bool, usage string) *[]bool {
  143. p := []bool{}
  144. f.BoolSliceVarP(&p, name, shorthand, value, usage)
  145. return &p
  146. }
  147. // BoolSlice defines a []bool flag with specified name, default value, and usage string.
  148. // The return value is the address of a []bool variable that stores the value of the flag.
  149. func BoolSlice(name string, value []bool, usage string) *[]bool {
  150. return CommandLine.BoolSliceP(name, "", value, usage)
  151. }
  152. // BoolSliceP is like BoolSlice, but accepts a shorthand letter that can be used after a single dash.
  153. func BoolSliceP(name, shorthand string, value []bool, usage string) *[]bool {
  154. return CommandLine.BoolSliceP(name, shorthand, value, usage)
  155. }