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