...

Source file src/gopkg.in/ini.v1/key.go

Documentation: gopkg.in/ini.v1

     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  }
   838  

View as plain text