...
1 package cli
2
3 import (
4 "encoding/json"
5 "flag"
6 "fmt"
7 "strconv"
8 "strings"
9 )
10
11
12 type Float64Slice struct {
13 slice []float64
14 separator separatorSpec
15 hasBeenSet bool
16 }
17
18
19 func NewFloat64Slice(defaults ...float64) *Float64Slice {
20 return &Float64Slice{slice: append([]float64{}, defaults...)}
21 }
22
23
24 func (f *Float64Slice) clone() *Float64Slice {
25 n := &Float64Slice{
26 slice: make([]float64, len(f.slice)),
27 hasBeenSet: f.hasBeenSet,
28 }
29 copy(n.slice, f.slice)
30 return n
31 }
32
33 func (f *Float64Slice) WithSeparatorSpec(spec separatorSpec) {
34 f.separator = spec
35 }
36
37
38 func (f *Float64Slice) Set(value string) error {
39 if !f.hasBeenSet {
40 f.slice = []float64{}
41 f.hasBeenSet = true
42 }
43
44 if strings.HasPrefix(value, slPfx) {
45
46 _ = json.Unmarshal([]byte(strings.Replace(value, slPfx, "", 1)), &f.slice)
47 f.hasBeenSet = true
48 return nil
49 }
50
51 for _, s := range f.separator.flagSplitMultiValues(value) {
52 tmp, err := strconv.ParseFloat(strings.TrimSpace(s), 64)
53 if err != nil {
54 return err
55 }
56
57 f.slice = append(f.slice, tmp)
58 }
59 return nil
60 }
61
62
63 func (f *Float64Slice) String() string {
64 v := f.slice
65 if v == nil {
66
67 v = make([]float64, 0)
68 }
69 return fmt.Sprintf("%#v", v)
70 }
71
72
73 func (f *Float64Slice) Serialize() string {
74 jsonBytes, _ := json.Marshal(f.slice)
75 return fmt.Sprintf("%s%s", slPfx, string(jsonBytes))
76 }
77
78
79 func (f *Float64Slice) Value() []float64 {
80 return f.slice
81 }
82
83
84 func (f *Float64Slice) Get() interface{} {
85 return *f
86 }
87
88
89
90 func (f *Float64SliceFlag) String() string {
91 return FlagStringer(f)
92 }
93
94
95 func (f *Float64SliceFlag) TakesValue() bool {
96 return true
97 }
98
99
100 func (f *Float64SliceFlag) GetUsage() string {
101 return f.Usage
102 }
103
104
105 func (f *Float64SliceFlag) GetCategory() string {
106 return f.Category
107 }
108
109
110
111 func (f *Float64SliceFlag) GetValue() string {
112 var defaultVals []string
113 if f.Value != nil && len(f.Value.Value()) > 0 {
114 for _, i := range f.Value.Value() {
115 defaultVals = append(defaultVals, strings.TrimRight(strings.TrimRight(fmt.Sprintf("%f", i), "0"), "."))
116 }
117 }
118 return strings.Join(defaultVals, ", ")
119 }
120
121
122 func (f *Float64SliceFlag) GetDefaultText() string {
123 if f.DefaultText != "" {
124 return f.DefaultText
125 }
126 return f.GetValue()
127 }
128
129
130 func (f *Float64SliceFlag) GetEnvVars() []string {
131 return f.EnvVars
132 }
133
134
135 func (f *Float64SliceFlag) IsSliceFlag() bool {
136 return true
137 }
138
139
140 func (f *Float64SliceFlag) Apply(set *flag.FlagSet) error {
141
142 if f.Destination != nil && f.Value != nil {
143 f.Destination.slice = make([]float64, len(f.Value.slice))
144 copy(f.Destination.slice, f.Value.slice)
145 }
146
147
148 var setValue *Float64Slice
149 switch {
150 case f.Destination != nil:
151 setValue = f.Destination
152 case f.Value != nil:
153 setValue = f.Value.clone()
154 default:
155 setValue = new(Float64Slice)
156 setValue.WithSeparatorSpec(f.separator)
157 }
158
159 if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
160 if 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 float64 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
174 for _, name := range f.Names() {
175 set.Var(setValue, name, f.Usage)
176 }
177
178 return nil
179 }
180
181 func (f *Float64SliceFlag) WithSeparatorSpec(spec separatorSpec) {
182 f.separator = spec
183 }
184
185
186 func (f *Float64SliceFlag) Get(ctx *Context) []float64 {
187 return ctx.Float64Slice(f.Name)
188 }
189
190
191 func (f *Float64SliceFlag) RunAction(c *Context) error {
192 if f.Action != nil {
193 return f.Action(c, c.Float64Slice(f.Name))
194 }
195
196 return nil
197 }
198
199
200
201 func (cCtx *Context) Float64Slice(name string) []float64 {
202 if fs := cCtx.lookupFlagSet(name); fs != nil {
203 return lookupFloat64Slice(name, fs)
204 }
205 return nil
206 }
207
208 func lookupFloat64Slice(name string, set *flag.FlagSet) []float64 {
209 f := set.Lookup(name)
210 if f != nil {
211 if slice, ok := unwrapFlagValue(f.Value).(*Float64Slice); ok {
212 return slice.Value()
213 }
214 }
215 return nil
216 }
217
View as plain text