...

Source file src/edge-infra.dev/pkg/lib/ini/key.go

Documentation: edge-infra.dev/pkg/lib/ini

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

View as plain text