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) }