init commit

master
timest 2018-07-10 21:00:31 +08:00
commit 2e16b70e4a
2 changed files with 165 additions and 0 deletions

15
.gitignore vendored Normal file
View File

@ -0,0 +1,15 @@
# Created by .ignore support plugin (hsz.mobi)
### Go template
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
# Test binary, build with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out

150
env.go Normal file
View File

@ -0,0 +1,150 @@
package env
import (
"reflect"
"strings"
"log"
"strconv"
"os"
"fmt"
"time"
)
var (
DEFAULT_SEPARATOR = "_"
)
func upper(v string) string {
return strings.ToUpper(v)
}
func Fill(v interface{}) error {
if reflect.ValueOf(v).Kind() != reflect.Ptr {
return fmt.Errorf("Fill只接受指针类型的值")
}
//for _, v := range os.Environ() {
// if strings.HasPrefix(v, "CONFIG") {
// log.Print(v)
// }
//}
ind := reflect.Indirect(reflect.ValueOf(v))
prefix := upper(ind.Type().Name())
err := fill(prefix, ind)
if err != nil {
return err
}
return nil
}
func combine(p, n string, v string, ok bool) string{
if !ok {
return p + DEFAULT_SEPARATOR + n
}
return p + v + n
}
func parseBool(v string) (bool, error) {
if v == "" {
return false, nil
}
return strconv.ParseBool(v)
}
func fill(pf string, ind reflect.Value) error{
for i := 0; i < ind.NumField(); i++ {
f := ind.Type().Field(i)
name := f.Name
envName, exist := f.Tag.Lookup("env")
if exist {
name = envName
}
s, exist := f.Tag.Lookup("sep")
p := combine(pf, upper(name), s, exist)
switch ind.Field(i).Kind() {
case reflect.Struct:
err := fill(p, ind.Field(i))
if err != nil {
return err
}
default:
err := parse(p, ind.Field(i), f)
if err != nil {
return err
}
}
}
return nil
}
func parse(prefix string, f reflect.Value, sf reflect.StructField) error {
log.Print("parse:", prefix, f.String(), f.Type().String(), f.Kind().String())
df := sf.Tag.Get("default")
isRequire, err := parseBool(sf.Tag.Get("require"))
if err != nil {
return fmt.Errorf("字段:%s require不是合法的布尔值支持: 1 t T true TRUE True.", prefix)
}
ev, exist := os.LookupEnv(prefix)
if !exist && isRequire {
return fmt.Errorf("%s 是必须的变量,但没有被设置", prefix)
}
if !exist && df != "" {
ev = df
}
log.Print("ev:", ev)
switch f.Kind() {
case reflect.String:
f.SetString(df)
case reflect.Int:
iv, err := strconv.ParseInt(ev, 10, 32)
if err != nil {
return err
}
f.SetInt(iv)
case reflect.Int64:
if f.Type().String() == "time.Duration" {
t, err := time.ParseDuration(ev)
if err != nil {
return err
}
f.Set(reflect.ValueOf(t))
} else {
iv, err := strconv.ParseInt(ev, 10, 64)
if err != nil {
return err
}
f.SetInt(iv)
}
case reflect.Uint:
uiv, err := strconv.ParseUint(ev, 10, 32)
if err != nil {
return err
}
f.SetUint(uiv)
case reflect.Uint64:
uiv, err := strconv.ParseUint(ev, 10, 64)
if err != nil {
return err
}
f.SetUint(uiv)
case reflect.Float32:
f32, err := strconv.ParseFloat(ev, 32)
if err != nil {
return err
}
f.SetFloat(f32)
case reflect.Float64:
f64, err := strconv.ParseFloat(ev, 64)
if err != nil {
return err
}
f.SetFloat(f64)
case reflect.Bool:
b, err := parseBool(ev)
if err != nil {
return err
}
f.SetBool(b)
}
return nil
}