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  }