github.com/treeverse/lakefs@v1.24.1-0.20240520134607-95648127bfb0/pkg/config/types.go (about)

     1  package config
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"reflect"
     7  	"strings"
     8  )
     9  
    10  // Strings is a []string that mapstructure can deserialize from a single string or from a list
    11  // of strings.
    12  type Strings []string
    13  
    14  var (
    15  	ourStringsType  = reflect.TypeOf(Strings{})
    16  	stringType      = reflect.TypeOf("")
    17  	stringSliceType = reflect.TypeOf([]string{})
    18  )
    19  
    20  // DecodeStrings is a mapstructure.HookFuncType that decodes a single string value or a slice
    21  // of strings into Strings.
    22  func DecodeStrings(fromValue reflect.Value, toValue reflect.Value) (interface{}, error) {
    23  	if toValue.Type() != ourStringsType {
    24  		return fromValue.Interface(), nil
    25  	}
    26  	if fromValue.Type() == stringSliceType {
    27  		return Strings(fromValue.Interface().([]string)), nil
    28  	}
    29  	if fromValue.Type() == stringType {
    30  		return Strings(strings.Split(fromValue.String(), ",")), nil
    31  	}
    32  	return fromValue.Interface(), nil
    33  }
    34  
    35  type SecureString string
    36  
    37  // String returns an elided version.  It is safe to call for logging.
    38  func (SecureString) String() string {
    39  	return "[SECRET]"
    40  }
    41  
    42  // SecureValue returns the actual value of s as a string.
    43  func (s SecureString) SecureValue() string {
    44  	return string(s)
    45  }
    46  
    47  // OnlyString is a string that can deserialize only from a string.  Use it
    48  // to prevent YAML configuration reading a number-like string with leading
    49  // zeros, and then Viper using mapstructure to convert it silently back to a
    50  // string and losing the leading zeros.
    51  type OnlyString string
    52  
    53  var (
    54  	onlyStringType  = reflect.TypeOf(OnlyString(""))
    55  	ErrMustBeString = errors.New("must be a string")
    56  )
    57  
    58  func (o OnlyString) String() string {
    59  	return string(o)
    60  }
    61  
    62  // DecodeOnlyString is a mapstructure.HookFuncType that decodes a string
    63  // value as an OnlyString, but fails on all other values.  It is useful to
    64  // force parsing of a field that can contain just digits as a string, when
    65  // the leading digit might be 0.
    66  func DecodeOnlyString(fromValue reflect.Value, toValue reflect.Value) (interface{}, error) {
    67  	if toValue.Type() != onlyStringType {
    68  		// Not trying to translate to OnlyString
    69  		return fromValue.Interface(), nil
    70  	}
    71  	if fromValue.Type() != stringType {
    72  		return nil, fmt.Errorf("%w, not a %s", ErrMustBeString, fromValue.Type().String())
    73  	}
    74  	return OnlyString(fromValue.Interface().(string)), nil
    75  }