1 package cli
2
3 import (
4 "encoding/json"
5 "flag"
6 "fmt"
7 "strconv"
8 "strings"
9 )
10
11
12 type Uint64Slice struct {
13 slice []uint64
14 separator separatorSpec
15 hasBeenSet bool
16 }
17
18
19 func NewUint64Slice(defaults ...uint64) *Uint64Slice {
20 return &Uint64Slice{slice: append([]uint64{}, defaults...)}
21 }
22
23
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
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
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
64 func (i *Uint64Slice) String() string {
65 v := i.slice
66 if v == nil {
67
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
78 func (i *Uint64Slice) Serialize() string {
79 jsonBytes, _ := json.Marshal(i.slice)
80 return fmt.Sprintf("%s%s", slPfx, string(jsonBytes))
81 }
82
83
84 func (i *Uint64Slice) Value() []uint64 {
85 return i.slice
86 }
87
88
89 func (i *Uint64Slice) Get() interface{} {
90 return *i
91 }
92
93
94
95 func (f *Uint64SliceFlag) String() string {
96 return FlagStringer(f)
97 }
98
99
100 func (f *Uint64SliceFlag) TakesValue() bool {
101 return true
102 }
103
104
105 func (f *Uint64SliceFlag) GetUsage() string {
106 return f.Usage
107 }
108
109
110 func (f *Uint64SliceFlag) GetCategory() string {
111 return f.Category
112 }
113
114
115
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
127 func (f *Uint64SliceFlag) GetDefaultText() string {
128 if f.DefaultText != "" {
129 return f.DefaultText
130 }
131 return f.GetValue()
132 }
133
134
135 func (f *Uint64SliceFlag) GetEnvVars() []string {
136 return f.EnvVars
137 }
138
139
140 func (f *Uint64SliceFlag) IsSliceFlag() bool {
141 return true
142 }
143
144
145 func (f *Uint64SliceFlag) Apply(set *flag.FlagSet) error {
146
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
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
172
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
189 func (f *Uint64SliceFlag) Get(ctx *Context) []uint64 {
190 return ctx.Uint64Slice(f.Name)
191 }
192
193
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
203
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