replace zxq.co/ripple/hanayo
This commit is contained in:
165
vendor/github.com/thehowl/conf/conf.go
generated
vendored
Normal file
165
vendor/github.com/thehowl/conf/conf.go
generated
vendored
Normal file
@@ -0,0 +1,165 @@
|
||||
// Package conf lets you manage configuration files in the easiest way possible, without the unnecessary pain.
|
||||
package conf
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// The only custom errors this package will return.
|
||||
var (
|
||||
ErrNoFile = errors.New("conf: the configuration file doesn't exist")
|
||||
ErrNotAStruct = errors.New("conf: the passed into/from variable is not a pointer to a struct")
|
||||
)
|
||||
|
||||
// Load unmarshals a file into the struct passed as the argument "into".
|
||||
func Load(into interface{}, filename string) error {
|
||||
intoValue := reflect.ValueOf(into)
|
||||
if intoValue.Kind() != reflect.Ptr || intoValue.Elem().Kind() != reflect.Struct {
|
||||
return ErrNotAStruct
|
||||
}
|
||||
intoValue = intoValue.Elem()
|
||||
f, err := ioutil.ReadFile(filename)
|
||||
if os.IsNotExist(err) {
|
||||
return ErrNoFile
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return loadRaw(intoValue, f)
|
||||
}
|
||||
|
||||
// LoadRaw allows you to load into a struct some raw data bytes.
|
||||
func LoadRaw(into interface{}, data []byte) error {
|
||||
intoValue := reflect.ValueOf(into)
|
||||
if intoValue.Kind() != reflect.Ptr || intoValue.Elem().Kind() != reflect.Struct {
|
||||
return ErrNotAStruct
|
||||
}
|
||||
intoValue = intoValue.Elem()
|
||||
return loadRaw(intoValue, data)
|
||||
}
|
||||
|
||||
func loadRaw(intoValue reflect.Value, data []byte) error {
|
||||
fvs := Parse(data)
|
||||
for _, v := range fvs {
|
||||
for i := 0; i < intoValue.Type().NumField(); i++ {
|
||||
field := intoValue.Type().Field(i)
|
||||
if !intoValue.Field(i).CanSet() {
|
||||
continue
|
||||
}
|
||||
if field.Name == v.Field {
|
||||
switch field.Type.Kind() {
|
||||
case reflect.String:
|
||||
intoValue.Field(i).SetString(v.Value)
|
||||
case reflect.Bool:
|
||||
boolVal, err := strconv.ParseBool(v.Value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
intoValue.Field(i).SetBool(boolVal)
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
intVal, err := strconv.ParseInt(v.Value, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
intoValue.Field(i).SetInt(intVal)
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
uintVal, err := strconv.ParseUint(v.Value, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
intoValue.Field(i).SetUint(uintVal)
|
||||
case reflect.Float32, reflect.Float64:
|
||||
floatVal, err := strconv.ParseFloat(v.Value, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
intoValue.Field(i).SetFloat(floatVal)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MustLoad has the same behaviour as Load, but panics if it returns an error.
|
||||
func MustLoad(into interface{}, filename string) {
|
||||
if err := Load(into, filename); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// MustLoadRaw has the same behaviour as LoadRaw, but panics if it returns an error.
|
||||
func MustLoadRaw(into interface{}, data []byte) {
|
||||
if err := LoadRaw(into, data); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Export uses ExportRaw to put the data into a file, specified with its name.
|
||||
func Export(from interface{}, filename string) error {
|
||||
data, err := ExportRaw(from)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return ioutil.WriteFile(filename, data, 0644)
|
||||
}
|
||||
|
||||
// ExportRaw can create a []byte that can then be loaded back by LoadRaw to get a struct's original form back.
|
||||
// I suck at explaining stuff.
|
||||
func ExportRaw(from interface{}) ([]byte, error) {
|
||||
fromValue := reflect.ValueOf(from)
|
||||
if fromValue.Kind() == reflect.Ptr {
|
||||
return ExportRaw(fromValue.Elem().Interface())
|
||||
}
|
||||
if fromValue.Kind() != reflect.Struct {
|
||||
return []byte{}, ErrNotAStruct
|
||||
}
|
||||
return exportRaw(fromValue), nil
|
||||
}
|
||||
|
||||
func exportRaw(fromValue reflect.Value) []byte {
|
||||
var ret []byte
|
||||
for i := 0; i < fromValue.Type().NumField(); i++ {
|
||||
curfield := fromValue.Field(i)
|
||||
curfieldType := fromValue.Type().Field(i)
|
||||
|
||||
// Dirty hack to ignore that field if we don't support that type.
|
||||
if !((curfield.Kind() >= reflect.Bool && curfield.Kind() <= reflect.Uint64) ||
|
||||
curfield.Kind() == reflect.String || curfield.Kind() == reflect.Float32 ||
|
||||
curfield.Kind() == reflect.Float64) {
|
||||
continue
|
||||
}
|
||||
|
||||
/* guten */ tag := curfieldType.Tag.Get("description")
|
||||
if tag != "" {
|
||||
tag = strings.Replace(tag, "\n", "\n; ", -1)
|
||||
ret = append(ret, []byte("; "+tag+"\n")...)
|
||||
}
|
||||
ret = append(ret, []byte(Escape(curfieldType.Name)+"="+Escape(fmt.Sprint(curfield.Interface()))+"\n")...)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// MustExport panics if Export returns an error, removing error checking from your code. For the lazy.
|
||||
func MustExport(from interface{}, filename string) {
|
||||
if err := Export(from, filename); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// MustExportRaw panics if ExportRaw returns an error, removing error checking from your code. For the lazy.
|
||||
func MustExportRaw(from interface{}) []byte {
|
||||
data, err := ExportRaw(from)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return data
|
||||
}
|
Reference in New Issue
Block a user