...

Source file src/github.com/urfave/cli/v2/altsrc/toml_file_loader.go

Documentation: github.com/urfave/cli/v2/altsrc

     1  package altsrc
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  
     7  	"github.com/BurntSushi/toml"
     8  	"github.com/urfave/cli/v2"
     9  )
    10  
    11  type tomlMap struct {
    12  	Map map[interface{}]interface{}
    13  }
    14  
    15  func unmarshalMap(i interface{}) (ret map[interface{}]interface{}, err error) {
    16  	ret = make(map[interface{}]interface{})
    17  	m := i.(map[string]interface{})
    18  	for key, val := range m {
    19  		v := reflect.ValueOf(val)
    20  		switch v.Kind() {
    21  		case reflect.Bool:
    22  			ret[key] = val.(bool)
    23  		case reflect.String:
    24  			ret[key] = val.(string)
    25  		case reflect.Int:
    26  			ret[key] = val.(int)
    27  		case reflect.Int8:
    28  			ret[key] = int(val.(int8))
    29  		case reflect.Int16:
    30  			ret[key] = int(val.(int16))
    31  		case reflect.Int32:
    32  			ret[key] = int(val.(int32))
    33  		case reflect.Int64:
    34  			ret[key] = int(val.(int64))
    35  		case reflect.Uint:
    36  			ret[key] = int(val.(uint))
    37  		case reflect.Uint8:
    38  			ret[key] = int(val.(uint8))
    39  		case reflect.Uint16:
    40  			ret[key] = int(val.(uint16))
    41  		case reflect.Uint32:
    42  			ret[key] = int(val.(uint32))
    43  		case reflect.Uint64:
    44  			ret[key] = int(val.(uint64))
    45  		case reflect.Float32:
    46  			ret[key] = float64(val.(float32))
    47  		case reflect.Float64:
    48  			ret[key] = val.(float64)
    49  		case reflect.Map:
    50  			if tmp, err := unmarshalMap(val); err == nil {
    51  				ret[key] = tmp
    52  			} else {
    53  				return nil, err
    54  			}
    55  		case reflect.Array, reflect.Slice:
    56  			ret[key] = val.([]interface{})
    57  		default:
    58  			return nil, fmt.Errorf("Unsupported: type = %#v", v.Kind())
    59  		}
    60  	}
    61  	return ret, nil
    62  }
    63  
    64  func (tm *tomlMap) UnmarshalTOML(i interface{}) error {
    65  	if tmp, err := unmarshalMap(i); err == nil {
    66  		tm.Map = tmp
    67  	} else {
    68  		return err
    69  	}
    70  	return nil
    71  }
    72  
    73  type tomlSourceContext struct {
    74  	FilePath string
    75  }
    76  
    77  // NewTomlSourceFromFile creates a new TOML InputSourceContext from a filepath.
    78  func NewTomlSourceFromFile(file string) (InputSourceContext, error) {
    79  	tsc := &tomlSourceContext{FilePath: file}
    80  	var results tomlMap = tomlMap{}
    81  	if err := readCommandToml(tsc.FilePath, &results); err != nil {
    82  		return nil, fmt.Errorf("Unable to load TOML file '%s': inner error: \n'%v'", tsc.FilePath, err.Error())
    83  	}
    84  	return &MapInputSource{file: file, valueMap: results.Map}, nil
    85  }
    86  
    87  // NewTomlSourceFromFlagFunc creates a new TOML InputSourceContext from a provided flag name and source context.
    88  func NewTomlSourceFromFlagFunc(flagFileName string) func(cCtx *cli.Context) (InputSourceContext, error) {
    89  	return func(cCtx *cli.Context) (InputSourceContext, error) {
    90  		if cCtx.IsSet(flagFileName) {
    91  			filePath := cCtx.String(flagFileName)
    92  			return NewTomlSourceFromFile(filePath)
    93  		}
    94  
    95  		return defaultInputSource()
    96  	}
    97  }
    98  
    99  func readCommandToml(filePath string, container interface{}) (err error) {
   100  	b, err := loadDataFrom(filePath)
   101  	if err != nil {
   102  		return err
   103  	}
   104  
   105  	err = toml.Unmarshal(b, container)
   106  	if err != nil {
   107  		return err
   108  	}
   109  
   110  	err = nil
   111  	return
   112  }
   113  

View as plain text