...

Source file src/github.com/urfave/cli/v2/flag_uint64_slice.go

Documentation: github.com/urfave/cli/v2

     1  package cli
     2  
     3  import (
     4  	"encoding/json"
     5  	"flag"
     6  	"fmt"
     7  	"strconv"
     8  	"strings"
     9  )
    10  
    11  // Uint64Slice wraps []int64 to satisfy flag.Value
    12  type Uint64Slice struct {
    13  	slice      []uint64
    14  	separator  separatorSpec
    15  	hasBeenSet bool
    16  }
    17  
    18  // NewUint64Slice makes an *Uint64Slice with default values
    19  func NewUint64Slice(defaults ...uint64) *Uint64Slice {
    20  	return &Uint64Slice{slice: append([]uint64{}, defaults...)}
    21  }
    22  
    23  // clone allocate a copy of self object
    24  func (i *Uint64Slice) clone() *Uint64Slice {
    25  	n := &Uint64Slice{
    26  		slice:      make([]uint64, len(i.slice)),
    27  		hasBeenSet: i.hasBeenSet,
    28  	}
    29  	copy(n.slice, i.slice)
    30  	return n
    31  }
    32  
    33  // Set parses the value into an integer and appends it to the list of values
    34  func (i *Uint64Slice) Set(value string) error {
    35  	if !i.hasBeenSet {
    36  		i.slice = []uint64{}
    37  		i.hasBeenSet = true
    38  	}
    39  
    40  	if strings.HasPrefix(value, slPfx) {
    41  		// Deserializing assumes overwrite
    42  		_ = json.Unmarshal([]byte(strings.Replace(value, slPfx, "", 1)), &i.slice)
    43  		i.hasBeenSet = true
    44  		return nil
    45  	}
    46  
    47  	for _, s := range i.separator.flagSplitMultiValues(value) {
    48  		tmp, err := strconv.ParseUint(strings.TrimSpace(s), 0, 64)
    49  		if err != nil {
    50  			return err
    51  		}
    52  
    53  		i.slice = append(i.slice, tmp)
    54  	}
    55  
    56  	return nil
    57  }
    58  
    59  func (i *Uint64Slice) WithSeparatorSpec(spec separatorSpec) {
    60  	i.separator = spec
    61  }
    62  
    63  // String returns a readable representation of this value (for usage defaults)
    64  func (i *Uint64Slice) String() string {
    65  	v := i.slice
    66  	if v == nil {
    67  		// treat nil the same as zero length non-nil
    68  		v = make([]uint64, 0)
    69  	}
    70  	str := fmt.Sprintf("%d", v)
    71  	str = strings.Replace(str, " ", ", ", -1)
    72  	str = strings.Replace(str, "[", "{", -1)
    73  	str = strings.Replace(str, "]", "}", -1)
    74  	return fmt.Sprintf("[]uint64%s", str)
    75  }
    76  
    77  // Serialize allows Uint64Slice to fulfill Serializer
    78  func (i *Uint64Slice) Serialize() string {
    79  	jsonBytes, _ := json.Marshal(i.slice)
    80  	return fmt.Sprintf("%s%s", slPfx, string(jsonBytes))
    81  }
    82  
    83  // Value returns the slice of ints set by this flag
    84  func (i *Uint64Slice) Value() []uint64 {
    85  	return i.slice
    86  }
    87  
    88  // Get returns the slice of ints set by this flag
    89  func (i *Uint64Slice) Get() interface{} {
    90  	return *i
    91  }
    92  
    93  // String returns a readable representation of this value
    94  // (for usage defaults)
    95  func (f *Uint64SliceFlag) String() string {
    96  	return FlagStringer(f)
    97  }
    98  
    99  // TakesValue returns true of the flag takes a value, otherwise false
   100  func (f *Uint64SliceFlag) TakesValue() bool {
   101  	return true
   102  }
   103  
   104  // GetUsage returns the usage string for the flag
   105  func (f *Uint64SliceFlag) GetUsage() string {
   106  	return f.Usage
   107  }
   108  
   109  // GetCategory returns the category for the flag
   110  func (f *Uint64SliceFlag) GetCategory() string {
   111  	return f.Category
   112  }
   113  
   114  // GetValue returns the flags value as string representation and an empty
   115  // string if the flag takes no value at all.
   116  func (f *Uint64SliceFlag) GetValue() string {
   117  	var defaultVals []string
   118  	if f.Value != nil && len(f.Value.Value()) > 0 {
   119  		for _, i := range f.Value.Value() {
   120  			defaultVals = append(defaultVals, strconv.FormatUint(i, 10))
   121  		}
   122  	}
   123  	return strings.Join(defaultVals, ", ")
   124  }
   125  
   126  // GetDefaultText returns the default text for this flag
   127  func (f *Uint64SliceFlag) GetDefaultText() string {
   128  	if f.DefaultText != "" {
   129  		return f.DefaultText
   130  	}
   131  	return f.GetValue()
   132  }
   133  
   134  // GetEnvVars returns the env vars for this flag
   135  func (f *Uint64SliceFlag) GetEnvVars() []string {
   136  	return f.EnvVars
   137  }
   138  
   139  // IsSliceFlag implements DocGenerationSliceFlag.
   140  func (f *Uint64SliceFlag) IsSliceFlag() bool {
   141  	return true
   142  }
   143  
   144  // Apply populates the flag given the flag set and environment
   145  func (f *Uint64SliceFlag) Apply(set *flag.FlagSet) error {
   146  	// apply any default
   147  	if f.Destination != nil && f.Value != nil {
   148  		f.Destination.slice = make([]uint64, len(f.Value.slice))
   149  		copy(f.Destination.slice, f.Value.slice)
   150  	}
   151  
   152  	// resolve setValue (what we will assign to the set)
   153  	var setValue *Uint64Slice
   154  	switch {
   155  	case f.Destination != nil:
   156  		setValue = f.Destination
   157  	case f.Value != nil:
   158  		setValue = f.Value.clone()
   159  	default:
   160  		setValue = new(Uint64Slice)
   161  		setValue.WithSeparatorSpec(f.separator)
   162  	}
   163  
   164  	if val, source, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok && val != "" {
   165  		for _, s := range f.separator.flagSplitMultiValues(val) {
   166  			if err := setValue.Set(strings.TrimSpace(s)); err != nil {
   167  				return fmt.Errorf("could not parse %q as uint64 slice value from %s for flag %s: %s", val, source, f.Name, err)
   168  			}
   169  		}
   170  
   171  		// Set this to false so that we reset the slice if we then set values from
   172  		// flags that have already been set by the environment.
   173  		setValue.hasBeenSet = false
   174  		f.HasBeenSet = true
   175  	}
   176  
   177  	for _, name := range f.Names() {
   178  		set.Var(setValue, name, f.Usage)
   179  	}
   180  
   181  	return nil
   182  }
   183  
   184  func (f *Uint64SliceFlag) WithSeparatorSpec(spec separatorSpec) {
   185  	f.separator = spec
   186  }
   187  
   188  // Get returns the flag’s value in the given Context.
   189  func (f *Uint64SliceFlag) Get(ctx *Context) []uint64 {
   190  	return ctx.Uint64Slice(f.Name)
   191  }
   192  
   193  // RunAction executes flag action if set
   194  func (f *Uint64SliceFlag) RunAction(c *Context) error {
   195  	if f.Action != nil {
   196  		return f.Action(c, c.Uint64Slice(f.Name))
   197  	}
   198  
   199  	return nil
   200  }
   201  
   202  // Uint64Slice looks up the value of a local Uint64SliceFlag, returns
   203  // nil if not found
   204  func (cCtx *Context) Uint64Slice(name string) []uint64 {
   205  	if fs := cCtx.lookupFlagSet(name); fs != nil {
   206  		return lookupUint64Slice(name, fs)
   207  	}
   208  	return nil
   209  }
   210  
   211  func lookupUint64Slice(name string, set *flag.FlagSet) []uint64 {
   212  	f := set.Lookup(name)
   213  	if f != nil {
   214  		if slice, ok := unwrapFlagValue(f.Value).(*Uint64Slice); ok {
   215  			return slice.Value()
   216  		}
   217  	}
   218  	return nil
   219  }
   220  

View as plain text