github.com/shrimpyuk/bor@v0.2.15-0.20220224151350-fb4ec6020bae/internal/cli/flagset/flagset.go (about) 1 package flagset 2 3 import ( 4 "flag" 5 "fmt" 6 "math/big" 7 "strings" 8 "time" 9 ) 10 11 type Flagset struct { 12 flags []*FlagVar 13 set *flag.FlagSet 14 } 15 16 func NewFlagSet(name string) *Flagset { 17 f := &Flagset{ 18 flags: []*FlagVar{}, 19 set: flag.NewFlagSet(name, flag.ContinueOnError), 20 } 21 return f 22 } 23 24 type FlagVar struct { 25 Name string 26 Usage string 27 } 28 29 func (f *Flagset) addFlag(fl *FlagVar) { 30 f.flags = append(f.flags, fl) 31 } 32 33 func (f *Flagset) Help() string { 34 str := "Options:\n\n" 35 items := []string{} 36 for _, item := range f.flags { 37 items = append(items, fmt.Sprintf(" -%s\n %s", item.Name, item.Usage)) 38 } 39 return str + strings.Join(items, "\n\n") 40 } 41 42 func (f *Flagset) Parse(args []string) error { 43 return f.set.Parse(args) 44 } 45 46 func (f *Flagset) Args() []string { 47 return f.set.Args() 48 } 49 50 type BoolFlag struct { 51 Name string 52 Usage string 53 Default bool 54 Value *bool 55 } 56 57 func (f *Flagset) BoolFlag(b *BoolFlag) { 58 f.addFlag(&FlagVar{ 59 Name: b.Name, 60 Usage: b.Usage, 61 }) 62 f.set.BoolVar(b.Value, b.Name, b.Default, b.Usage) 63 } 64 65 type StringFlag struct { 66 Name string 67 Usage string 68 Default string 69 Value *string 70 } 71 72 func (f *Flagset) StringFlag(b *StringFlag) { 73 f.addFlag(&FlagVar{ 74 Name: b.Name, 75 Usage: b.Usage, 76 }) 77 f.set.StringVar(b.Value, b.Name, b.Default, b.Usage) 78 } 79 80 type IntFlag struct { 81 Name string 82 Usage string 83 Value *int 84 Default int 85 } 86 87 func (f *Flagset) IntFlag(i *IntFlag) { 88 f.addFlag(&FlagVar{ 89 Name: i.Name, 90 Usage: i.Usage, 91 }) 92 f.set.IntVar(i.Value, i.Name, i.Default, i.Usage) 93 } 94 95 type Uint64Flag struct { 96 Name string 97 Usage string 98 Value *uint64 99 Default uint64 100 } 101 102 func (f *Flagset) Uint64Flag(i *Uint64Flag) { 103 f.addFlag(&FlagVar{ 104 Name: i.Name, 105 Usage: i.Usage, 106 }) 107 f.set.Uint64Var(i.Value, i.Name, i.Default, i.Usage) 108 } 109 110 type BigIntFlag struct { 111 Name string 112 Usage string 113 Value *big.Int 114 } 115 116 func (b *BigIntFlag) String() string { 117 if b.Value == nil { 118 return "" 119 } 120 return b.Value.String() 121 } 122 123 func (b *BigIntFlag) Set(value string) error { 124 num := new(big.Int) 125 126 var ok bool 127 if strings.HasPrefix(value, "0x") { 128 num, ok = num.SetString(value[2:], 16) 129 } else { 130 num, ok = num.SetString(value, 10) 131 } 132 if !ok { 133 return fmt.Errorf("failed to set big int") 134 } 135 b.Value = num 136 return nil 137 } 138 139 func (f *Flagset) BigIntFlag(b *BigIntFlag) { 140 f.addFlag(&FlagVar{ 141 Name: b.Name, 142 Usage: b.Usage, 143 }) 144 f.set.Var(b, b.Name, b.Usage) 145 } 146 147 type SliceStringFlag struct { 148 Name string 149 Usage string 150 Value *[]string 151 } 152 153 func (i *SliceStringFlag) String() string { 154 if i.Value == nil { 155 return "" 156 } 157 return strings.Join(*i.Value, ",") 158 } 159 160 func (i *SliceStringFlag) Set(value string) error { 161 *i.Value = append(*i.Value, strings.Split(value, ",")...) 162 return nil 163 } 164 165 func (f *Flagset) SliceStringFlag(s *SliceStringFlag) { 166 f.addFlag(&FlagVar{ 167 Name: s.Name, 168 Usage: s.Usage, 169 }) 170 f.set.Var(s, s.Name, s.Usage) 171 } 172 173 type DurationFlag struct { 174 Name string 175 Usage string 176 Value *time.Duration 177 Default time.Duration 178 } 179 180 func (f *Flagset) DurationFlag(d *DurationFlag) { 181 f.addFlag(&FlagVar{ 182 Name: d.Name, 183 Usage: d.Usage, 184 }) 185 f.set.DurationVar(d.Value, d.Name, d.Default, "") 186 } 187 188 type MapStringFlag struct { 189 Name string 190 Usage string 191 Value *map[string]string 192 } 193 194 func (m *MapStringFlag) String() string { 195 if m.Value == nil { 196 return "" 197 } 198 ls := []string{} 199 for k, v := range *m.Value { 200 ls = append(ls, k+"="+v) 201 } 202 return strings.Join(ls, ",") 203 } 204 205 func (m *MapStringFlag) Set(value string) error { 206 if m.Value == nil { 207 m.Value = &map[string]string{} 208 } 209 for _, t := range strings.Split(value, ",") { 210 if t != "" { 211 kv := strings.Split(t, "=") 212 213 if len(kv) == 2 { 214 (*m.Value)[kv[0]] = kv[1] 215 } 216 } 217 } 218 return nil 219 } 220 221 func (f *Flagset) MapStringFlag(m *MapStringFlag) { 222 f.addFlag(&FlagVar{ 223 Name: m.Name, 224 Usage: m.Usage, 225 }) 226 f.set.Var(m, m.Name, m.Usage) 227 } 228 229 type Float64Flag struct { 230 Name string 231 Usage string 232 Value *float64 233 Default float64 234 } 235 236 func (f *Flagset) Float64Flag(i *Float64Flag) { 237 f.addFlag(&FlagVar{ 238 Name: i.Name, 239 Usage: i.Usage, 240 }) 241 f.set.Float64Var(i.Value, i.Name, i.Default, "") 242 }