...
1 package cli
2
3 import (
4 "encoding/json"
5 "flag"
6 "fmt"
7 "strconv"
8 "strings"
9 )
10
11
12 type Int64Slice struct {
13 slice []int64
14 separator separatorSpec
15 hasBeenSet bool
16 }
17
18
19 func NewInt64Slice(defaults ...int64) *Int64Slice {
20 return &Int64Slice{slice: append([]int64{}, defaults...)}
21 }
22
23
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
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
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
64 func (i *Int64Slice) String() string {
65 v := i.slice
66 if v == nil {
67
68 v = make([]int64, 0)
69 }
70 return fmt.Sprintf("%#v", v)
71 }
72
73
74 func (i *Int64Slice) Serialize() string {
75 jsonBytes, _ := json.Marshal(i.slice)
76 return fmt.Sprintf("%s%s", slPfx, string(jsonBytes))
77 }
78
79
80 func (i *Int64Slice) Value() []int64 {
81 return i.slice
82 }
83
84
85 func (i *Int64Slice) Get() interface{} {
86 return *i
87 }
88
89
90
91 func (f *Int64SliceFlag) String() string {
92 return FlagStringer(f)
93 }
94
95
96 func (f *Int64SliceFlag) TakesValue() bool {
97 return true
98 }
99
100
101 func (f *Int64SliceFlag) GetUsage() string {
102 return f.Usage
103 }
104
105
106 func (f *Int64SliceFlag) GetCategory() string {
107 return f.Category
108 }
109
110
111
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
123 func (f *Int64SliceFlag) GetDefaultText() string {
124 if f.DefaultText != "" {
125 return f.DefaultText
126 }
127 return f.GetValue()
128 }
129
130
131 func (f *Int64SliceFlag) GetEnvVars() []string {
132 return f.EnvVars
133 }
134
135
136 func (f *Int64SliceFlag) IsSliceFlag() bool {
137 return true
138 }
139
140
141 func (f *Int64SliceFlag) Apply(set *flag.FlagSet) error {
142
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
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
168
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
185 func (f *Int64SliceFlag) Get(ctx *Context) []int64 {
186 return ctx.Int64Slice(f.Name)
187 }
188
189
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
199
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