init commit
This commit is contained in:
commit
2e16b70e4a
15
.gitignore
vendored
Normal file
15
.gitignore
vendored
Normal 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
150
env.go
Normal 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
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user