bool_slice.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  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 boolSliceConv(val string) (interface{}, error) {
  59. val = strings.Trim(val, "[]")
  60. // Empty string would cause a slice with one (empty) entry
  61. if len(val) == 0 {
  62. return []bool{}, nil
  63. }
  64. ss := strings.Split(val, ",")
  65. out := make([]bool, len(ss))
  66. for i, t := range ss {
  67. var err error
  68. out[i], err = strconv.ParseBool(t)
  69. if err != nil {
  70. return nil, err
  71. }
  72. }
  73. return out, nil
  74. }
  75. // GetBoolSlice returns the []bool value of a flag with the given name.
  76. func (f *FlagSet) GetBoolSlice(name string) ([]bool, error) {
  77. val, err := f.getFlagType(name, "boolSlice", boolSliceConv)
  78. if err != nil {
  79. return []bool{}, err
  80. }
  81. return val.([]bool), nil
  82. }
  83. // BoolSliceVar defines a boolSlice flag with specified name, default value, and usage string.
  84. // The argument p points to a []bool variable in which to store the value of the flag.
  85. func (f *FlagSet) BoolSliceVar(p *[]bool, name string, value []bool, usage string) {
  86. f.VarP(newBoolSliceValue(value, p), name, "", usage)
  87. }
  88. // BoolSliceVarP is like BoolSliceVar, but accepts a shorthand letter that can be used after a single dash.
  89. func (f *FlagSet) BoolSliceVarP(p *[]bool, name, shorthand string, value []bool, usage string) {
  90. f.VarP(newBoolSliceValue(value, p), name, shorthand, usage)
  91. }
  92. // BoolSliceVar defines a []bool flag with specified name, default value, and usage string.
  93. // The argument p points to a []bool variable in which to store the value of the flag.
  94. func BoolSliceVar(p *[]bool, name string, value []bool, usage string) {
  95. CommandLine.VarP(newBoolSliceValue(value, p), name, "", usage)
  96. }
  97. // BoolSliceVarP is like BoolSliceVar, but accepts a shorthand letter that can be used after a single dash.
  98. func BoolSliceVarP(p *[]bool, name, shorthand string, value []bool, usage string) {
  99. CommandLine.VarP(newBoolSliceValue(value, p), name, shorthand, usage)
  100. }
  101. // BoolSlice defines a []bool flag with specified name, default value, and usage string.
  102. // The return value is the address of a []bool variable that stores the value of the flag.
  103. func (f *FlagSet) BoolSlice(name string, value []bool, usage string) *[]bool {
  104. p := []bool{}
  105. f.BoolSliceVarP(&p, name, "", value, usage)
  106. return &p
  107. }
  108. // BoolSliceP is like BoolSlice, but accepts a shorthand letter that can be used after a single dash.
  109. func (f *FlagSet) BoolSliceP(name, shorthand string, value []bool, usage string) *[]bool {
  110. p := []bool{}
  111. f.BoolSliceVarP(&p, name, shorthand, value, usage)
  112. return &p
  113. }
  114. // BoolSlice defines a []bool flag with specified name, default value, and usage string.
  115. // The return value is the address of a []bool variable that stores the value of the flag.
  116. func BoolSlice(name string, value []bool, usage string) *[]bool {
  117. return CommandLine.BoolSliceP(name, "", value, usage)
  118. }
  119. // BoolSliceP is like BoolSlice, but accepts a shorthand letter that can be used after a single dash.
  120. func BoolSliceP(name, shorthand string, value []bool, usage string) *[]bool {
  121. return CommandLine.BoolSliceP(name, shorthand, value, usage)
  122. }