bool_slice.go raw

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