251
|
1 |
// Copyright 2014 Unknwon |
|
2 |
// |
|
3 |
// Licensed under the Apache License, Version 2.0 (the "License"): you may |
|
4 |
// not use this file except in compliance with the License. You may obtain |
|
5 |
// a copy of the License at |
|
6 |
// |
|
7 |
// http://www.apache.org/licenses/LICENSE-2.0 |
|
8 |
// |
|
9 |
// Unless required by applicable law or agreed to in writing, software |
|
10 |
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
|
11 |
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
|
12 |
// License for the specific language governing permissions and limitations |
|
13 |
// under the License. |
|
14 |
|
|
15 |
package ini |
|
16 |
|
|
17 |
import ( |
|
18 |
"bytes" |
|
19 |
"errors" |
|
20 |
"fmt" |
|
21 |
"strconv" |
|
22 |
"strings" |
|
23 |
"time" |
|
24 |
) |
|
25 |
|
|
26 |
// Key represents a key under a section. |
|
27 |
type Key struct { |
|
28 |
s *Section |
|
29 |
Comment string |
|
30 |
name string |
|
31 |
value string |
|
32 |
isAutoIncrement bool |
|
33 |
isBooleanType bool |
|
34 |
|
|
35 |
isShadow bool |
|
36 |
shadows []*Key |
|
37 |
|
|
38 |
nestedValues []string |
|
39 |
} |
|
40 |
|
|
41 |
// newKey simply return a key object with given values. |
|
42 |
func newKey(s *Section, name, val string) *Key { |
|
43 |
return &Key{ |
|
44 |
s: s, |
|
45 |
name: name, |
|
46 |
value: val, |
|
47 |
} |
|
48 |
} |
|
49 |
|
|
50 |
func (k *Key) addShadow(val string) error { |
|
51 |
if k.isShadow { |
|
52 |
return errors.New("cannot add shadow to another shadow key") |
|
53 |
} else if k.isAutoIncrement || k.isBooleanType { |
|
54 |
return errors.New("cannot add shadow to auto-increment or boolean key") |
|
55 |
} |
|
56 |
|
|
57 |
// Deduplicate shadows based on their values. |
|
58 |
if k.value == val { |
|
59 |
return nil |
|
60 |
} |
|
61 |
for i := range k.shadows { |
|
62 |
if k.shadows[i].value == val { |
|
63 |
return nil |
|
64 |
} |
|
65 |
} |
|
66 |
|
|
67 |
shadow := newKey(k.s, k.name, val) |
|
68 |
shadow.isShadow = true |
|
69 |
k.shadows = append(k.shadows, shadow) |
|
70 |
return nil |
|
71 |
} |
|
72 |
|
|
73 |
// AddShadow adds a new shadow key to itself. |
|
74 |
func (k *Key) AddShadow(val string) error { |
|
75 |
if !k.s.f.options.AllowShadows { |
|
76 |
return errors.New("shadow key is not allowed") |
|
77 |
} |
|
78 |
return k.addShadow(val) |
|
79 |
} |
|
80 |
|
|
81 |
func (k *Key) addNestedValue(val string) error { |
|
82 |
if k.isAutoIncrement || k.isBooleanType { |
|
83 |
return errors.New("cannot add nested value to auto-increment or boolean key") |
|
84 |
} |
|
85 |
|
|
86 |
k.nestedValues = append(k.nestedValues, val) |
|
87 |
return nil |
|
88 |
} |
|
89 |
|
|
90 |
// AddNestedValue adds a nested value to the key. |
|
91 |
func (k *Key) AddNestedValue(val string) error { |
|
92 |
if !k.s.f.options.AllowNestedValues { |
|
93 |
return errors.New("nested value is not allowed") |
|
94 |
} |
|
95 |
return k.addNestedValue(val) |
|
96 |
} |
|
97 |
|
|
98 |
// ValueMapper represents a mapping function for values, e.g. os.ExpandEnv |
|
99 |
type ValueMapper func(string) string |
|
100 |
|
|
101 |
// Name returns name of key. |
|
102 |
func (k *Key) Name() string { |
|
103 |
return k.name |
|
104 |
} |
|
105 |
|
|
106 |
// Value returns raw value of key for performance purpose. |
|
107 |
func (k *Key) Value() string { |
|
108 |
return k.value |
|
109 |
} |
|
110 |
|
|
111 |
// ValueWithShadows returns raw values of key and its shadows if any. |
|
112 |
func (k *Key) ValueWithShadows() []string { |
|
113 |
if len(k.shadows) == 0 { |
|
114 |
return []string{k.value} |
|
115 |
} |
|
116 |
vals := make([]string, len(k.shadows)+1) |
|
117 |
vals[0] = k.value |
|
118 |
for i := range k.shadows { |
|
119 |
vals[i+1] = k.shadows[i].value |
|
120 |
} |
|
121 |
return vals |
|
122 |
} |
|
123 |
|
|
124 |
// NestedValues returns nested values stored in the key. |
|
125 |
// It is possible returned value is nil if no nested values stored in the key. |
|
126 |
func (k *Key) NestedValues() []string { |
|
127 |
return k.nestedValues |
|
128 |
} |
|
129 |
|
|
130 |
// transformValue takes a raw value and transforms to its final string. |
|
131 |
func (k *Key) transformValue(val string) string { |
|
132 |
if k.s.f.ValueMapper != nil { |
|
133 |
val = k.s.f.ValueMapper(val) |
|
134 |
} |
|
135 |
|
|
136 |
// Fail-fast if no indicate char found for recursive value |
|
137 |
if !strings.Contains(val, "%") { |
|
138 |
return val |
|
139 |
} |
|
140 |
for i := 0; i < depthValues; i++ { |
|
141 |
vr := varPattern.FindString(val) |
|
142 |
if len(vr) == 0 { |
|
143 |
break |
|
144 |
} |
|
145 |
|
|
146 |
// Take off leading '%(' and trailing ')s'. |
|
147 |
noption := vr[2 : len(vr)-2] |
|
148 |
|
|
149 |
// Search in the same section. |
|
150 |
// If not found or found the key itself, then search again in default section. |
|
151 |
nk, err := k.s.GetKey(noption) |
|
152 |
if err != nil || k == nk { |
|
153 |
nk, _ = k.s.f.Section("").GetKey(noption) |
|
154 |
if nk == nil { |
|
155 |
// Stop when no results found in the default section, |
|
156 |
// and returns the value as-is. |
|
157 |
break |
|
158 |
} |
|
159 |
} |
|
160 |
|
|
161 |
// Substitute by new value and take off leading '%(' and trailing ')s'. |
|
162 |
val = strings.Replace(val, vr, nk.value, -1) |
|
163 |
} |
|
164 |
return val |
|
165 |
} |
|
166 |
|
|
167 |
// String returns string representation of value. |
|
168 |
func (k *Key) String() string { |
|
169 |
return k.transformValue(k.value) |
|
170 |
} |
|
171 |
|
|
172 |
// Validate accepts a validate function which can |
|
173 |
// return modifed result as key value. |
|
174 |
func (k *Key) Validate(fn func(string) string) string { |
|
175 |
return fn(k.String()) |
|
176 |
} |
|
177 |
|
|
178 |
// parseBool returns the boolean value represented by the string. |
|
179 |
// |
|
180 |
// It accepts 1, t, T, TRUE, true, True, YES, yes, Yes, y, ON, on, On, |
|
181 |
// 0, f, F, FALSE, false, False, NO, no, No, n, OFF, off, Off. |
|
182 |
// Any other value returns an error. |
|
183 |
func parseBool(str string) (value bool, err error) { |
|
184 |
switch str { |
|
185 |
case "1", "t", "T", "true", "TRUE", "True", "YES", "yes", "Yes", "y", "ON", "on", "On": |
|
186 |
return true, nil |
|
187 |
case "0", "f", "F", "false", "FALSE", "False", "NO", "no", "No", "n", "OFF", "off", "Off": |
|
188 |
return false, nil |
|
189 |
} |
|
190 |
return false, fmt.Errorf("parsing \"%s\": invalid syntax", str) |
|
191 |
} |
|
192 |
|
|
193 |
// Bool returns bool type value. |
|
194 |
func (k *Key) Bool() (bool, error) { |
|
195 |
return parseBool(k.String()) |
|
196 |
} |
|
197 |
|
|
198 |
// Float64 returns float64 type value. |
|
199 |
func (k *Key) Float64() (float64, error) { |
|
200 |
return strconv.ParseFloat(k.String(), 64) |
|
201 |
} |
|
202 |
|
|
203 |
// Int returns int type value. |
|
204 |
func (k *Key) Int() (int, error) { |
|
205 |
v, err := strconv.ParseInt(k.String(), 0, 64) |
|
206 |
return int(v), err |
|
207 |
} |
|
208 |
|
|
209 |
// Int64 returns int64 type value. |
|
210 |
func (k *Key) Int64() (int64, error) { |
|
211 |
return strconv.ParseInt(k.String(), 0, 64) |
|
212 |
} |
|
213 |
|
|
214 |
// Uint returns uint type valued. |
|
215 |
func (k *Key) Uint() (uint, error) { |
|
216 |
u, e := strconv.ParseUint(k.String(), 0, 64) |
|
217 |
return uint(u), e |
|
218 |
} |
|
219 |
|
|
220 |
// Uint64 returns uint64 type value. |
|
221 |
func (k *Key) Uint64() (uint64, error) { |
|
222 |
return strconv.ParseUint(k.String(), 0, 64) |
|
223 |
} |
|
224 |
|
|
225 |
// Duration returns time.Duration type value. |
|
226 |
func (k *Key) Duration() (time.Duration, error) { |
|
227 |
return time.ParseDuration(k.String()) |
|
228 |
} |
|
229 |
|
|
230 |
// TimeFormat parses with given format and returns time.Time type value. |
|
231 |
func (k *Key) TimeFormat(format string) (time.Time, error) { |
|
232 |
return time.Parse(format, k.String()) |
|
233 |
} |
|
234 |
|
|
235 |
// Time parses with RFC3339 format and returns time.Time type value. |
|
236 |
func (k *Key) Time() (time.Time, error) { |
|
237 |
return k.TimeFormat(time.RFC3339) |
|
238 |
} |
|
239 |
|
|
240 |
// MustString returns default value if key value is empty. |
|
241 |
func (k *Key) MustString(defaultVal string) string { |
|
242 |
val := k.String() |
|
243 |
if len(val) == 0 { |
|
244 |
k.value = defaultVal |
|
245 |
return defaultVal |
|
246 |
} |
|
247 |
return val |
|
248 |
} |
|
249 |
|
|
250 |
// MustBool always returns value without error, |
|
251 |
// it returns false if error occurs. |
|
252 |
func (k *Key) MustBool(defaultVal ...bool) bool { |
|
253 |
val, err := k.Bool() |
|
254 |
if len(defaultVal) > 0 && err != nil { |
|
255 |
k.value = strconv.FormatBool(defaultVal[0]) |
|
256 |
return defaultVal[0] |
|
257 |
} |
|
258 |
return val |
|
259 |
} |
|
260 |
|
|
261 |
// MustFloat64 always returns value without error, |
|
262 |
// it returns 0.0 if error occurs. |
|
263 |
func (k *Key) MustFloat64(defaultVal ...float64) float64 { |
|
264 |
val, err := k.Float64() |
|
265 |
if len(defaultVal) > 0 && err != nil { |
|
266 |
k.value = strconv.FormatFloat(defaultVal[0], 'f', -1, 64) |
|
267 |
return defaultVal[0] |
|
268 |
} |
|
269 |
return val |
|
270 |
} |
|
271 |
|
|
272 |
// MustInt always returns value without error, |
|
273 |
// it returns 0 if error occurs. |
|
274 |
func (k *Key) MustInt(defaultVal ...int) int { |
|
275 |
val, err := k.Int() |
|
276 |
if len(defaultVal) > 0 && err != nil { |
|
277 |
k.value = strconv.FormatInt(int64(defaultVal[0]), 10) |
|
278 |
return defaultVal[0] |
|
279 |
} |
|
280 |
return val |
|
281 |
} |
|
282 |
|
|
283 |
// MustInt64 always returns value without error, |
|
284 |
// it returns 0 if error occurs. |
|
285 |
func (k *Key) MustInt64(defaultVal ...int64) int64 { |
|
286 |
val, err := k.Int64() |
|
287 |
if len(defaultVal) > 0 && err != nil { |
|
288 |
k.value = strconv.FormatInt(defaultVal[0], 10) |
|
289 |
return defaultVal[0] |
|
290 |
} |
|
291 |
return val |
|
292 |
} |
|
293 |
|
|
294 |
// MustUint always returns value without error, |
|
295 |
// it returns 0 if error occurs. |
|
296 |
func (k *Key) MustUint(defaultVal ...uint) uint { |
|
297 |
val, err := k.Uint() |
|
298 |
if len(defaultVal) > 0 && err != nil { |
|
299 |
k.value = strconv.FormatUint(uint64(defaultVal[0]), 10) |
|
300 |
return defaultVal[0] |
|
301 |
} |
|
302 |
return val |
|
303 |
} |
|
304 |
|
|
305 |
// MustUint64 always returns value without error, |
|
306 |
// it returns 0 if error occurs. |
|
307 |
func (k *Key) MustUint64(defaultVal ...uint64) uint64 { |
|
308 |
val, err := k.Uint64() |
|
309 |
if len(defaultVal) > 0 && err != nil { |
|
310 |
k.value = strconv.FormatUint(defaultVal[0], 10) |
|
311 |
return defaultVal[0] |
|
312 |
} |
|
313 |
return val |
|
314 |
} |
|
315 |
|
|
316 |
// MustDuration always returns value without error, |
|
317 |
// it returns zero value if error occurs. |
|
318 |
func (k *Key) MustDuration(defaultVal ...time.Duration) time.Duration { |
|
319 |
val, err := k.Duration() |
|
320 |
if len(defaultVal) > 0 && err != nil { |
|
321 |
k.value = defaultVal[0].String() |
|
322 |
return defaultVal[0] |
|
323 |
} |
|
324 |
return val |
|
325 |
} |
|
326 |
|
|
327 |
// MustTimeFormat always parses with given format and returns value without error, |
|
328 |
// it returns zero value if error occurs. |
|
329 |
func (k *Key) MustTimeFormat(format string, defaultVal ...time.Time) time.Time { |
|
330 |
val, err := k.TimeFormat(format) |
|
331 |
if len(defaultVal) > 0 && err != nil { |
|
332 |
k.value = defaultVal[0].Format(format) |
|
333 |
return defaultVal[0] |
|
334 |
} |
|
335 |
return val |
|
336 |
} |
|
337 |
|
|
338 |
// MustTime always parses with RFC3339 format and returns value without error, |
|
339 |
// it returns zero value if error occurs. |
|
340 |
func (k *Key) MustTime(defaultVal ...time.Time) time.Time { |
|
341 |
return k.MustTimeFormat(time.RFC3339, defaultVal...) |
|
342 |
} |
|
343 |
|
|
344 |
// In always returns value without error, |
|
345 |
// it returns default value if error occurs or doesn't fit into candidates. |
|
346 |
func (k *Key) In(defaultVal string, candidates []string) string { |
|
347 |
val := k.String() |
|
348 |
for _, cand := range candidates { |
|
349 |
if val == cand { |
|
350 |
return val |
|
351 |
} |
|
352 |
} |
|
353 |
return defaultVal |
|
354 |
} |
|
355 |
|
|
356 |
// InFloat64 always returns value without error, |
|
357 |
// it returns default value if error occurs or doesn't fit into candidates. |
|
358 |
func (k *Key) InFloat64(defaultVal float64, candidates []float64) float64 { |
|
359 |
val := k.MustFloat64() |
|
360 |
for _, cand := range candidates { |
|
361 |
if val == cand { |
|
362 |
return val |
|
363 |
} |
|
364 |
} |
|
365 |
return defaultVal |
|
366 |
} |
|
367 |
|
|
368 |
// InInt always returns value without error, |
|
369 |
// it returns default value if error occurs or doesn't fit into candidates. |
|
370 |
func (k *Key) InInt(defaultVal int, candidates []int) int { |
|
371 |
val := k.MustInt() |
|
372 |
for _, cand := range candidates { |
|
373 |
if val == cand { |
|
374 |
return val |
|
375 |
} |
|
376 |
} |
|
377 |
return defaultVal |
|
378 |
} |
|
379 |
|
|
380 |
// InInt64 always returns value without error, |
|
381 |
// it returns default value if error occurs or doesn't fit into candidates. |
|
382 |
func (k *Key) InInt64(defaultVal int64, candidates []int64) int64 { |
|
383 |
val := k.MustInt64() |
|
384 |
for _, cand := range candidates { |
|
385 |
if val == cand { |
|
386 |
return val |
|
387 |
} |
|
388 |
} |
|
389 |
return defaultVal |
|
390 |
} |
|
391 |
|
|
392 |
// InUint always returns value without error, |
|
393 |
// it returns default value if error occurs or doesn't fit into candidates. |
|
394 |
func (k *Key) InUint(defaultVal uint, candidates []uint) uint { |
|
395 |
val := k.MustUint() |
|
396 |
for _, cand := range candidates { |
|
397 |
if val == cand { |
|
398 |
return val |
|
399 |
} |
|
400 |
} |
|
401 |
return defaultVal |
|
402 |
} |
|
403 |
|
|
404 |
// InUint64 always returns value without error, |
|
405 |
// it returns default value if error occurs or doesn't fit into candidates. |
|
406 |
func (k *Key) InUint64(defaultVal uint64, candidates []uint64) uint64 { |
|
407 |
val := k.MustUint64() |
|
408 |
for _, cand := range candidates { |
|
409 |
if val == cand { |
|
410 |
return val |
|
411 |
} |
|
412 |
} |
|
413 |
return defaultVal |
|
414 |
} |
|
415 |
|
|
416 |
// InTimeFormat always parses with given format and returns value without error, |
|
417 |
// it returns default value if error occurs or doesn't fit into candidates. |
|
418 |
func (k *Key) InTimeFormat(format string, defaultVal time.Time, candidates []time.Time) time.Time { |
|
419 |
val := k.MustTimeFormat(format) |
|
420 |
for _, cand := range candidates { |
|
421 |
if val == cand { |
|
422 |
return val |
|
423 |
} |
|
424 |
} |
|
425 |
return defaultVal |
|
426 |
} |
|
427 |
|
|
428 |
// InTime always parses with RFC3339 format and returns value without error, |
|
429 |
// it returns default value if error occurs or doesn't fit into candidates. |
|
430 |
func (k *Key) InTime(defaultVal time.Time, candidates []time.Time) time.Time { |
|
431 |
return k.InTimeFormat(time.RFC3339, defaultVal, candidates) |
|
432 |
} |
|
433 |
|
|
434 |
// RangeFloat64 checks if value is in given range inclusively, |
|
435 |
// and returns default value if it's not. |
|
436 |
func (k *Key) RangeFloat64(defaultVal, min, max float64) float64 { |
|
437 |
val := k.MustFloat64() |
|
438 |
if val < min || val > max { |
|
439 |
return defaultVal |
|
440 |
} |
|
441 |
return val |
|
442 |
} |
|
443 |
|
|
444 |
// RangeInt checks if value is in given range inclusively, |
|
445 |
// and returns default value if it's not. |
|
446 |
func (k *Key) RangeInt(defaultVal, min, max int) int { |
|
447 |
val := k.MustInt() |
|
448 |
if val < min || val > max { |
|
449 |
return defaultVal |
|
450 |
} |
|
451 |
return val |
|
452 |
} |
|
453 |
|
|
454 |
// RangeInt64 checks if value is in given range inclusively, |
|
455 |
// and returns default value if it's not. |
|
456 |
func (k *Key) RangeInt64(defaultVal, min, max int64) int64 { |
|
457 |
val := k.MustInt64() |
|
458 |
if val < min || val > max { |
|
459 |
return defaultVal |
|
460 |
} |
|
461 |
return val |
|
462 |
} |
|
463 |
|
|
464 |
// RangeTimeFormat checks if value with given format is in given range inclusively, |
|
465 |
// and returns default value if it's not. |
|
466 |
func (k *Key) RangeTimeFormat(format string, defaultVal, min, max time.Time) time.Time { |
|
467 |
val := k.MustTimeFormat(format) |
|
468 |
if val.Unix() < min.Unix() || val.Unix() > max.Unix() { |
|
469 |
return defaultVal |
|
470 |
} |
|
471 |
return val |
|
472 |
} |
|
473 |
|
|
474 |
// RangeTime checks if value with RFC3339 format is in given range inclusively, |
|
475 |
// and returns default value if it's not. |
|
476 |
func (k *Key) RangeTime(defaultVal, min, max time.Time) time.Time { |
|
477 |
return k.RangeTimeFormat(time.RFC3339, defaultVal, min, max) |
|
478 |
} |
|
479 |
|
|
480 |
// Strings returns list of string divided by given delimiter. |
|
481 |
func (k *Key) Strings(delim string) []string { |
|
482 |
str := k.String() |
|
483 |
if len(str) == 0 { |
|
484 |
return []string{} |
|
485 |
} |
|
486 |
|
|
487 |
runes := []rune(str) |
|
488 |
vals := make([]string, 0, 2) |
|
489 |
var buf bytes.Buffer |
|
490 |
escape := false |
|
491 |
idx := 0 |
|
492 |
for { |
|
493 |
if escape { |
|
494 |
escape = false |
|
495 |
if runes[idx] != '\\' && !strings.HasPrefix(string(runes[idx:]), delim) { |
|
496 |
buf.WriteRune('\\') |
|
497 |
} |
|
498 |
buf.WriteRune(runes[idx]) |
|
499 |
} else { |
|
500 |
if runes[idx] == '\\' { |
|
501 |
escape = true |
|
502 |
} else if strings.HasPrefix(string(runes[idx:]), delim) { |
|
503 |
idx += len(delim) - 1 |
|
504 |
vals = append(vals, strings.TrimSpace(buf.String())) |
|
505 |
buf.Reset() |
|
506 |
} else { |
|
507 |
buf.WriteRune(runes[idx]) |
|
508 |
} |
|
509 |
} |
|
510 |
idx++ |
|
511 |
if idx == len(runes) { |
|
512 |
break |
|
513 |
} |
|
514 |
} |
|
515 |
|
|
516 |
if buf.Len() > 0 { |
|
517 |
vals = append(vals, strings.TrimSpace(buf.String())) |
|
518 |
} |
|
519 |
|
|
520 |
return vals |
|
521 |
} |
|
522 |
|
|
523 |
// StringsWithShadows returns list of string divided by given delimiter. |
|
524 |
// Shadows will also be appended if any. |
|
525 |
func (k *Key) StringsWithShadows(delim string) []string { |
|
526 |
vals := k.ValueWithShadows() |
|
527 |
results := make([]string, 0, len(vals)*2) |
|
528 |
for i := range vals { |
|
529 |
if len(vals) == 0 { |
|
530 |
continue |
|
531 |
} |
|
532 |
|
|
533 |
results = append(results, strings.Split(vals[i], delim)...) |
|
534 |
} |
|
535 |
|
|
536 |
for i := range results { |
|
537 |
results[i] = k.transformValue(strings.TrimSpace(results[i])) |
|
538 |
} |
|
539 |
return results |
|
540 |
} |
|
541 |
|
|
542 |
// Float64s returns list of float64 divided by given delimiter. Any invalid input will be treated as zero value. |
|
543 |
func (k *Key) Float64s(delim string) []float64 { |
|
544 |
vals, _ := k.parseFloat64s(k.Strings(delim), true, false) |
|
545 |
return vals |
|
546 |
} |
|
547 |
|
|
548 |
// Ints returns list of int divided by given delimiter. Any invalid input will be treated as zero value. |
|
549 |
func (k *Key) Ints(delim string) []int { |
|
550 |
vals, _ := k.parseInts(k.Strings(delim), true, false) |
|
551 |
return vals |
|
552 |
} |
|
553 |
|
|
554 |
// Int64s returns list of int64 divided by given delimiter. Any invalid input will be treated as zero value. |
|
555 |
func (k *Key) Int64s(delim string) []int64 { |
|
556 |
vals, _ := k.parseInt64s(k.Strings(delim), true, false) |
|
557 |
return vals |
|
558 |
} |
|
559 |
|
|
560 |
// Uints returns list of uint divided by given delimiter. Any invalid input will be treated as zero value. |
|
561 |
func (k *Key) Uints(delim string) []uint { |
|
562 |
vals, _ := k.parseUints(k.Strings(delim), true, false) |
|
563 |
return vals |
|
564 |
} |
|
565 |
|
|
566 |
// Uint64s returns list of uint64 divided by given delimiter. Any invalid input will be treated as zero value. |
|
567 |
func (k *Key) Uint64s(delim string) []uint64 { |
|
568 |
vals, _ := k.parseUint64s(k.Strings(delim), true, false) |
|
569 |
return vals |
|
570 |
} |
|
571 |
|
|
572 |
// Bools returns list of bool divided by given delimiter. Any invalid input will be treated as zero value. |
|
573 |
func (k *Key) Bools(delim string) []bool { |
|
574 |
vals, _ := k.parseBools(k.Strings(delim), true, false) |
|
575 |
return vals |
|
576 |
} |
|
577 |
|
|
578 |
// TimesFormat parses with given format and returns list of time.Time divided by given delimiter. |
|
579 |
// Any invalid input will be treated as zero value (0001-01-01 00:00:00 +0000 UTC). |
|
580 |
func (k *Key) TimesFormat(format, delim string) []time.Time { |
|
581 |
vals, _ := k.parseTimesFormat(format, k.Strings(delim), true, false) |
|
582 |
return vals |
|
583 |
} |
|
584 |
|
|
585 |
// Times parses with RFC3339 format and returns list of time.Time divided by given delimiter. |
|
586 |
// Any invalid input will be treated as zero value (0001-01-01 00:00:00 +0000 UTC). |
|
587 |
func (k *Key) Times(delim string) []time.Time { |
|
588 |
return k.TimesFormat(time.RFC3339, delim) |
|
589 |
} |
|
590 |
|
|
591 |
// ValidFloat64s returns list of float64 divided by given delimiter. If some value is not float, then |
|
592 |
// it will not be included to result list. |
|
593 |
func (k *Key) ValidFloat64s(delim string) []float64 { |
|
594 |
vals, _ := k.parseFloat64s(k.Strings(delim), false, false) |
|
595 |
return vals |
|
596 |
} |
|
597 |
|
|
598 |
// ValidInts returns list of int divided by given delimiter. If some value is not integer, then it will |
|
599 |
// not be included to result list. |
|
600 |
func (k *Key) ValidInts(delim string) []int { |
|
601 |
vals, _ := k.parseInts(k.Strings(delim), false, false) |
|
602 |
return vals |
|
603 |
} |
|
604 |
|
|
605 |
// ValidInt64s returns list of int64 divided by given delimiter. If some value is not 64-bit integer, |
|
606 |
// then it will not be included to result list. |
|
607 |
func (k *Key) ValidInt64s(delim string) []int64 { |
|
608 |
vals, _ := k.parseInt64s(k.Strings(delim), false, false) |
|
609 |
return vals |
|
610 |
} |
|
611 |
|
|
612 |
// ValidUints returns list of uint divided by given delimiter. If some value is not unsigned integer, |
|
613 |
// then it will not be included to result list. |
|
614 |
func (k *Key) ValidUints(delim string) []uint { |
|
615 |
vals, _ := k.parseUints(k.Strings(delim), false, false) |
|
616 |
return vals |
|
617 |
} |
|
618 |
|
|
619 |
// ValidUint64s returns list of uint64 divided by given delimiter. If some value is not 64-bit unsigned |
|
620 |
// integer, then it will not be included to result list. |
|
621 |
func (k *Key) ValidUint64s(delim string) []uint64 { |
|
622 |
vals, _ := k.parseUint64s(k.Strings(delim), false, false) |
|
623 |
return vals |
|
624 |
} |
|
625 |
|
|
626 |
// ValidBools returns list of bool divided by given delimiter. If some value is not 64-bit unsigned |
|
627 |
// integer, then it will not be included to result list. |
|
628 |
func (k *Key) ValidBools(delim string) []bool { |
|
629 |
vals, _ := k.parseBools(k.Strings(delim), false, false) |
|
630 |
return vals |
|
631 |
} |
|
632 |
|
|
633 |
// ValidTimesFormat parses with given format and returns list of time.Time divided by given delimiter. |
|
634 |
func (k *Key) ValidTimesFormat(format, delim string) []time.Time { |
|
635 |
vals, _ := k.parseTimesFormat(format, k.Strings(delim), false, false) |
|
636 |
return vals |
|
637 |
} |
|
638 |
|
|
639 |
// ValidTimes parses with RFC3339 format and returns list of time.Time divided by given delimiter. |
|
640 |
func (k *Key) ValidTimes(delim string) []time.Time { |
|
641 |
return k.ValidTimesFormat(time.RFC3339, delim) |
|
642 |
} |
|
643 |
|
|
644 |
// StrictFloat64s returns list of float64 divided by given delimiter or error on first invalid input. |
|
645 |
func (k *Key) StrictFloat64s(delim string) ([]float64, error) { |
|
646 |
return k.parseFloat64s(k.Strings(delim), false, true) |
|
647 |
} |
|
648 |
|
|
649 |
// StrictInts returns list of int divided by given delimiter or error on first invalid input. |
|
650 |
func (k *Key) StrictInts(delim string) ([]int, error) { |
|
651 |
return k.parseInts(k.Strings(delim), false, true) |
|
652 |
} |
|
653 |
|
|
654 |
// StrictInt64s returns list of int64 divided by given delimiter or error on first invalid input. |
|
655 |
func (k *Key) StrictInt64s(delim string) ([]int64, error) { |
|
656 |
return k.parseInt64s(k.Strings(delim), false, true) |
|
657 |
} |
|
658 |
|
|
659 |
// StrictUints returns list of uint divided by given delimiter or error on first invalid input. |
|
660 |
func (k *Key) StrictUints(delim string) ([]uint, error) { |
|
661 |
return k.parseUints(k.Strings(delim), false, true) |
|
662 |
} |
|
663 |
|
|
664 |
// StrictUint64s returns list of uint64 divided by given delimiter or error on first invalid input. |
|
665 |
func (k *Key) StrictUint64s(delim string) ([]uint64, error) { |
|
666 |
return k.parseUint64s(k.Strings(delim), false, true) |
|
667 |
} |
|
668 |
|
|
669 |
// StrictBools returns list of bool divided by given delimiter or error on first invalid input. |
|
670 |
func (k *Key) StrictBools(delim string) ([]bool, error) { |
|
671 |
return k.parseBools(k.Strings(delim), false, true) |
|
672 |
} |
|
673 |
|
|
674 |
// StrictTimesFormat parses with given format and returns list of time.Time divided by given delimiter |
|
675 |
// or error on first invalid input. |
|
676 |
func (k *Key) StrictTimesFormat(format, delim string) ([]time.Time, error) { |
|
677 |
return k.parseTimesFormat(format, k.Strings(delim), false, true) |
|
678 |
} |
|
679 |
|
|
680 |
// StrictTimes parses with RFC3339 format and returns list of time.Time divided by given delimiter |
|
681 |
// or error on first invalid input. |
|
682 |
func (k *Key) StrictTimes(delim string) ([]time.Time, error) { |
|
683 |
return k.StrictTimesFormat(time.RFC3339, delim) |
|
684 |
} |
|
685 |
|
|
686 |
// parseBools transforms strings to bools. |
|
687 |
func (k *Key) parseBools(strs []string, addInvalid, returnOnInvalid bool) ([]bool, error) { |
|
688 |
vals := make([]bool, 0, len(strs)) |
|
689 |
for _, str := range strs { |
|
690 |
val, err := parseBool(str) |
|
691 |
if err != nil && returnOnInvalid { |
|
692 |
return nil, err |
|
693 |
} |
|
694 |
if err == nil || addInvalid { |
|
695 |
vals = append(vals, val) |
|
696 |
} |
|
697 |
} |
|
698 |
return vals, nil |
|
699 |
} |
|
700 |
|
|
701 |
// parseFloat64s transforms strings to float64s. |
|
702 |
func (k *Key) parseFloat64s(strs []string, addInvalid, returnOnInvalid bool) ([]float64, error) { |
|
703 |
vals := make([]float64, 0, len(strs)) |
|
704 |
for _, str := range strs { |
|
705 |
val, err := strconv.ParseFloat(str, 64) |
|
706 |
if err != nil && returnOnInvalid { |
|
707 |
return nil, err |
|
708 |
} |
|
709 |
if err == nil || addInvalid { |
|
710 |
vals = append(vals, val) |
|
711 |
} |
|
712 |
} |
|
713 |
return vals, nil |
|
714 |
} |
|
715 |
|
|
716 |
// parseInts transforms strings to ints. |
|
717 |
func (k *Key) parseInts(strs []string, addInvalid, returnOnInvalid bool) ([]int, error) { |
|
718 |
vals := make([]int, 0, len(strs)) |
|
719 |
for _, str := range strs { |
|
720 |
valInt64, err := strconv.ParseInt(str, 0, 64) |
|
721 |
val := int(valInt64) |
|
722 |
if err != nil && returnOnInvalid { |
|
723 |
return nil, err |
|
724 |
} |
|
725 |
if err == nil || addInvalid { |
|
726 |
vals = append(vals, val) |
|
727 |
} |
|
728 |
} |
|
729 |
return vals, nil |
|
730 |
} |
|
731 |
|
|
732 |
// parseInt64s transforms strings to int64s. |
|
733 |
func (k *Key) parseInt64s(strs []string, addInvalid, returnOnInvalid bool) ([]int64, error) { |
|
734 |
vals := make([]int64, 0, len(strs)) |
|
735 |
for _, str := range strs { |
|
736 |
val, err := strconv.ParseInt(str, 0, 64) |
|
737 |
if err != nil && returnOnInvalid { |
|
738 |
return nil, err |
|
739 |
} |
|
740 |
if err == nil || addInvalid { |
|
741 |
vals = append(vals, val) |
|
742 |
} |
|
743 |
} |
|
744 |
return vals, nil |
|
745 |
} |
|
746 |
|
|
747 |
// parseUints transforms strings to uints. |
|
748 |
func (k *Key) parseUints(strs []string, addInvalid, returnOnInvalid bool) ([]uint, error) { |
|
749 |
vals := make([]uint, 0, len(strs)) |
|
750 |
for _, str := range strs { |
|
751 |
val, err := strconv.ParseUint(str, 0, 0) |
|
752 |
if err != nil && returnOnInvalid { |
|
753 |
return nil, err |
|
754 |
} |
|
755 |
if err == nil || addInvalid { |
|
756 |
vals = append(vals, uint(val)) |
|
757 |
} |
|
758 |
} |
|
759 |
return vals, nil |
|
760 |
} |
|
761 |
|
|
762 |
// parseUint64s transforms strings to uint64s. |
|
763 |
func (k *Key) parseUint64s(strs []string, addInvalid, returnOnInvalid bool) ([]uint64, error) { |
|
764 |
vals := make([]uint64, 0, len(strs)) |
|
765 |
for _, str := range strs { |
|
766 |
val, err := strconv.ParseUint(str, 0, 64) |
|
767 |
if err != nil && returnOnInvalid { |
|
768 |
return nil, err |
|
769 |
} |
|
770 |
if err == nil || addInvalid { |
|
771 |
vals = append(vals, val) |
|
772 |
} |
|
773 |
} |
|
774 |
return vals, nil |
|
775 |
} |
|
776 |
|
|
777 |
// parseTimesFormat transforms strings to times in given format. |
|
778 |
func (k *Key) parseTimesFormat(format string, strs []string, addInvalid, returnOnInvalid bool) ([]time.Time, error) { |
|
779 |
vals := make([]time.Time, 0, len(strs)) |
|
780 |
for _, str := range strs { |
|
781 |
val, err := time.Parse(format, str) |
|
782 |
if err != nil && returnOnInvalid { |
|
783 |
return nil, err |
|
784 |
} |
|
785 |
if err == nil || addInvalid { |
|
786 |
vals = append(vals, val) |
|
787 |
} |
|
788 |
} |
|
789 |
return vals, nil |
|
790 |
} |
|
791 |
|
|
792 |
// SetValue changes key value. |
|
793 |
func (k *Key) SetValue(v string) { |
|
794 |
if k.s.f.BlockMode { |
|
795 |
k.s.f.lock.Lock() |
|
796 |
defer k.s.f.lock.Unlock() |
|
797 |
} |
|
798 |
|
|
799 |
k.value = v |
|
800 |
k.s.keysHash[k.name] = v |
|
801 |
} |