github.com/puellanivis/breton@v0.2.16/lib/gnuflag/enum.go (about) 1 package gnuflag 2 3 import ( 4 "errors" 5 "strconv" 6 "strings" 7 ) 8 9 // EnumValue defines an string-like flag type that maps strings to uint values. 10 // It is exported, so that it may be defined in a gnuflags.Struct parameter. 11 type EnumValue int 12 13 // enumValue describes a String flag that will only accept certain specific values. 14 type enumValue struct { 15 val *int 16 indices map[string]int 17 valid []string 18 } 19 20 // newEnumValue returns an EnumValue that will only accept the given strings. 21 func newEnumValue(valid ...string) *enumValue { 22 e := &enumValue{ 23 val: new(int), 24 } 25 26 e.setValid(valid) 27 28 return e 29 } 30 31 func (e *enumValue) setValid(valid []string) { 32 e.valid = valid 33 34 e.indices = make(map[string]int) 35 for i, v := range valid { 36 if v == "" { 37 continue 38 } 39 40 v = strings.ToUpper(v) 41 42 e.indices[v] = i 43 } 44 } 45 46 // ValueType permits an ability for the more standard flags library to support 47 // a flag displaying values/type allowed beyond the concrete types. 48 func (e *enumValue) ValueType() string { 49 var filtered []string 50 51 for _, v := range e.valid { 52 if v == "" { 53 continue 54 } 55 56 filtered = append(filtered, v) 57 } 58 59 return strings.Join(filtered, ", ") 60 } 61 62 // String returns the canonical valid string of the value of the EnumValue. 63 func (e *enumValue) String() string { 64 var val int 65 if e.val != nil { 66 val = *e.val 67 } 68 69 if val < 0 || val >= len(e.valid) { 70 return strconv.Itoa(val) 71 } 72 73 return e.valid[val] 74 } 75 76 // ErrBadEnum is the error returned when attempting to set an enum flag with a value not in the Enum 77 var ErrBadEnum = errors.New("bad enum value") 78 79 // Set attempts to set the given EnumValue to the given string. 80 func (e *enumValue) Set(s string) error { 81 if e.val == nil { 82 return errors.New("uninitialized enum usage") 83 } 84 85 if s == "" { 86 *e.val = 0 87 return nil 88 } 89 90 v, ok := e.indices[strings.ToUpper(s)] 91 if !ok { 92 return ErrBadEnum 93 } 94 95 *e.val = v 96 return nil 97 } 98 99 // Get returns the value of the enum flag. Expect it to be of type int. 100 func (e *enumValue) Get() interface{} { 101 if e.val == nil { 102 return 0 103 } 104 105 return *e.val 106 } 107 108 // Enum defines an enum flag with specified name, usage, and list of valid values. 109 // The return value is the address of an EnumValue variable that stores the value of the flag. 110 func (f *FlagSet) Enum(name string, usage string, valid []string, options ...Option) *EnumValue { 111 e := newEnumValue(valid...) 112 if err := f.Var(e, name, usage, options...); err != nil { 113 panic(err) 114 } 115 return (*EnumValue)(e.val) 116 } 117 118 // Enum defines an enum flag with specified name, usage, and list of valid values. 119 // The return value is the address of an EnumValue variable that stores the value of the flag. 120 func Enum(name string, usage string, valid []string, options ...Option) *EnumValue { 121 return CommandLine.Enum(name, usage, valid, options...) 122 }