leobot

Simple Telegram Logging Bot
git clone git://bsandro.tech/leobot
Log | Files | Refs | README | LICENSE

key.go (24405B)


      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 	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.
     76 func (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 
     83 func (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.
     93 func (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
    101 type ValueMapper func(string) string
    102 
    103 // Name returns name of key.
    104 func (k *Key) Name() string {
    105 	return k.name
    106 }
    107 
    108 // Value returns raw value of key for performance purpose.
    109 func (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.
    115 func (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.
    137 func (k *Key) NestedValues() []string {
    138 	return k.nestedValues
    139 }
    140 
    141 // transformValue takes a raw value and transforms to its final string.
    142 func (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.
    179 func (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.
    185 func (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.
    194 func 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.
    205 func (k *Key) Bool() (bool, error) {
    206 	return parseBool(k.String())
    207 }
    208 
    209 // Float64 returns float64 type value.
    210 func (k *Key) Float64() (float64, error) {
    211 	return strconv.ParseFloat(k.String(), 64)
    212 }
    213 
    214 // Int returns int type value.
    215 func (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.
    221 func (k *Key) Int64() (int64, error) {
    222 	return strconv.ParseInt(k.String(), 0, 64)
    223 }
    224 
    225 // Uint returns uint type valued.
    226 func (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.
    232 func (k *Key) Uint64() (uint64, error) {
    233 	return strconv.ParseUint(k.String(), 0, 64)
    234 }
    235 
    236 // Duration returns time.Duration type value.
    237 func (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.
    242 func (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.
    247 func (k *Key) Time() (time.Time, error) {
    248 	return k.TimeFormat(time.RFC3339)
    249 }
    250 
    251 // MustString returns default value if key value is empty.
    252 func (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.
    263 func (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.
    274 func (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.
    285 func (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.
    296 func (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.
    307 func (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.
    318 func (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.
    329 func (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.
    340 func (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.
    351 func (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.
    357 func (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.
    369 func (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.
    381 func (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.
    393 func (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.
    405 func (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.
    417 func (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.
    429 func (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.
    441 func (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.
    447 func (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.
    457 func (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.
    467 func (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.
    477 func (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.
    487 func (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.
    492 func (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.
    536 func (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.
    554 func (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.
    560 func (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.
    566 func (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.
    572 func (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.
    578 func (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.
    584 func (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).
    591 func (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).
    598 func (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.
    604 func (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.
    611 func (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.
    618 func (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.
    625 func (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.
    632 func (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.
    639 func (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.
    645 func (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.
    651 func (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.
    656 func (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.
    661 func (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.
    666 func (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.
    671 func (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.
    676 func (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.
    681 func (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.
    687 func (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.
    693 func (k *Key) StrictTimes(delim string) ([]time.Time, error) {
    694 	return k.StrictTimesFormat(time.RFC3339, delim)
    695 }
    696 
    697 // parseBools transforms strings to bools.
    698 func (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.
    714 func (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.
    730 func (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.
    746 func (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.
    763 func (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.
    780 func (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 
    795 type Parser func(str string) (interface{}, error)
    796 
    797 // parseTimesFormat transforms strings to times in given format.
    798 func (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
    814 func (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.
    829 func (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 }