...

Source file src/github.com/peterbourgon/ff/v3/ffyaml/ffyaml.go

Documentation: github.com/peterbourgon/ff/v3/ffyaml

     1  // Package ffyaml provides a YAML config file parser.
     2  package ffyaml
     3  
     4  import (
     5  	"fmt"
     6  	"io"
     7  	"strconv"
     8  
     9  	"github.com/peterbourgon/ff/v3"
    10  	"gopkg.in/yaml.v2"
    11  )
    12  
    13  // Parser is a parser for YAML file format. Flags and their values are read
    14  // from the key/value pairs defined in the config file.
    15  func Parser(r io.Reader, set func(name, value string) error) error {
    16  	var m map[string]interface{}
    17  	d := yaml.NewDecoder(r)
    18  	if err := d.Decode(&m); err != nil && err != io.EOF {
    19  		return ParseError{err}
    20  	}
    21  	for key, val := range m {
    22  		values, err := valsToStrs(val)
    23  		if err != nil {
    24  			return ParseError{err}
    25  		}
    26  		for _, value := range values {
    27  			if err := set(key, value); err != nil {
    28  				return err
    29  			}
    30  		}
    31  	}
    32  	return nil
    33  }
    34  
    35  func valsToStrs(val interface{}) ([]string, error) {
    36  	if vals, ok := val.([]interface{}); ok {
    37  		ss := make([]string, len(vals))
    38  		for i := range vals {
    39  			s, err := valToStr(vals[i])
    40  			if err != nil {
    41  				return nil, err
    42  			}
    43  			ss[i] = s
    44  		}
    45  		return ss, nil
    46  	}
    47  	s, err := valToStr(val)
    48  	if err != nil {
    49  		return nil, err
    50  	}
    51  	return []string{s}, nil
    52  
    53  }
    54  
    55  func valToStr(val interface{}) (string, error) {
    56  	switch v := val.(type) {
    57  	case byte:
    58  		return string([]byte{v}), nil
    59  	case string:
    60  		return v, nil
    61  	case bool:
    62  		return strconv.FormatBool(v), nil
    63  	case uint64:
    64  		return strconv.FormatUint(v, 10), nil
    65  	case int:
    66  		return strconv.Itoa(v), nil
    67  	case int64:
    68  		return strconv.FormatInt(v, 10), nil
    69  	case float64:
    70  		return strconv.FormatFloat(v, 'g', -1, 64), nil
    71  	case nil:
    72  		return "", nil
    73  	default:
    74  		return "", ff.StringConversionError{Value: val}
    75  	}
    76  }
    77  
    78  // ParseError wraps all errors originating from the YAML parser.
    79  type ParseError struct {
    80  	Inner error
    81  }
    82  
    83  // Error implenents the error interface.
    84  func (e ParseError) Error() string {
    85  	return fmt.Sprintf("error parsing YAML config: %v", e.Inner)
    86  }
    87  
    88  // Unwrap implements the errors.Wrapper interface, allowing errors.Is and
    89  // errors.As to work with ParseErrors.
    90  func (e ParseError) Unwrap() error {
    91  	return e.Inner
    92  }
    93  

View as plain text