...

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

View as plain text