github.com/nya3jp/tast@v0.0.0-20230601000426-85c8e4d83a9b/src/go.chromium.org/tast/core/internal/command/flags.go (about) 1 // Copyright 2018 The ChromiumOS Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package command 6 7 import ( 8 "fmt" 9 "sort" 10 "strconv" 11 "strings" 12 "time" 13 ) 14 15 // DurationFlag implements flag.Value to save a user-supplied integer time duration 16 // with fixed units to a time.Duration. 17 type DurationFlag struct { 18 units time.Duration 19 dst *time.Duration 20 } 21 22 // NewDurationFlag returns a DurationFlag that will save a duration with the supplied units to dst. 23 func NewDurationFlag(units time.Duration, dst *time.Duration, def time.Duration) *DurationFlag { 24 *dst = def 25 return &DurationFlag{units, dst} 26 } 27 28 // Set sets the flag value. 29 func (f *DurationFlag) Set(v string) error { 30 num, err := strconv.ParseInt(v, 10, 64) 31 if err != nil { 32 return err 33 } 34 *f.dst = time.Duration(num) * f.units 35 return nil 36 } 37 38 func (f *DurationFlag) String() string { return "" } 39 40 // EnumFlag implements flag.Value to map a user-supplied string value to an enum value. 41 type EnumFlag struct { 42 valid map[string]int // map from user-supplied string value to int value 43 assign EnumFlagAssignFunc // used to assign int value to dest 44 def string // default value 45 } 46 47 // EnumFlagAssignFunc is used by EnumFlag to assign an enum value to a target variable. 48 type EnumFlagAssignFunc func(val int) 49 50 // NewEnumFlag returns an EnumFlag using the supplied map of valid values and assignment function. 51 // def contains a default value to assign when the flag is unspecified. 52 func NewEnumFlag(valid map[string]int, assign EnumFlagAssignFunc, def string) *EnumFlag { 53 f := EnumFlag{valid, assign, def} 54 if err := f.Set(def); err != nil { 55 panic(err) 56 } 57 return &f 58 } 59 60 // Default returns the default value used if the flag is unset. 61 func (f *EnumFlag) Default() string { return f.def } 62 63 // QuotedValues returns a comma-separated list of quoted values the user can supply. 64 func (f *EnumFlag) QuotedValues() string { 65 var qn []string 66 for n := range f.valid { 67 qn = append(qn, fmt.Sprintf("%q", n)) 68 } 69 sort.Strings(qn) 70 return strings.Join(qn, ", ") 71 } 72 73 func (f *EnumFlag) String() string { return "" } 74 75 // Set sets the flag value. 76 func (f *EnumFlag) Set(v string) error { 77 ev, ok := f.valid[v] 78 if !ok { 79 return fmt.Errorf("must be in %s", f.QuotedValues()) 80 } 81 f.assign(ev) 82 return nil 83 } 84 85 // ListFlag implements flag.Value to split a user-supplied string with a custom delimiter 86 // into a slice of strings. 87 type ListFlag struct { 88 sep string // value separator, e.g. "," 89 assign ListFlagAssignFunc // used to assign slice value to dest 90 def []string // default value, e.g. []string{"foo", "bar"} 91 } 92 93 // ListFlagAssignFunc is called by ListFlag to assign a slice to a target variable. 94 type ListFlagAssignFunc func(vals []string) 95 96 // NewListFlag returns a ListFlag using the supplied separator and assignment function. 97 // def contains a default value to assign when the flag is unspecified. 98 func NewListFlag(sep string, assign ListFlagAssignFunc, def []string) *ListFlag { 99 f := ListFlag{sep, assign, def} 100 f.Set(f.Default()) 101 return &f 102 } 103 104 // Default returns the default value used if the flag is unset. 105 func (f *ListFlag) Default() string { return strings.Join(f.def, f.sep) } 106 107 func (f *ListFlag) String() string { return "" } 108 109 // Set sets the flag value. 110 func (f *ListFlag) Set(v string) error { 111 vals := strings.Split(v, f.sep) 112 if len(vals) == 1 && vals[0] == "" { 113 vals = nil 114 } 115 f.assign(vals) 116 return nil 117 } 118 119 // RepeatedFlag implements flag.Value around an assignment function that is executed each 120 // time the flag is supplied. 121 type RepeatedFlag func(v string) error 122 123 // Default returns the default value used if the flag is unset. 124 func (f *RepeatedFlag) Default() string { return "" } 125 126 func (f *RepeatedFlag) String() string { return "" } 127 128 // Set sets the flag value. 129 func (f *RepeatedFlag) Set(v string) error { return (*f)(v) }