Skip to content

Commit

Permalink
feat: obj-level functions (#13)
Browse files Browse the repository at this point in the history
feat: obj-level functions
  • Loading branch information
wrfly authored Dec 19, 2019
2 parents 8641e17 + d6840ba commit 73601f1
Show file tree
Hide file tree
Showing 8 changed files with 183 additions and 124 deletions.
122 changes: 81 additions & 41 deletions ecp.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,85 @@ import (
"strings"
)

type ecp struct {
GetKey GetKeyFunc
LookupValue LookupValueFunc
IgnoreKey IgnoreKeyFunc
LookupKey LookupKeyFunc

SplitChar string
}

var globalEcp = &ecp{
GetKey: getKeyFromEnv,
IgnoreKey: ignoreEnvKey,
LookupValue: lookupValueFromEnv,
LookupKey: lookupKey,
SplitChar: space,
}

// New ecp object
func New() *ecp {
return &ecp{
GetKey: getKeyFromEnv,
IgnoreKey: ignoreEnvKey,
LookupValue: lookupValueFromEnv,
LookupKey: lookupKey,
SplitChar: space,
}
}

func (e *ecp) Parse(config interface{}, prefix ...string) error {
if prefix == nil {
prefix = []string{"ECP"}
}
_, err := e.rangeOver(roOption{config, true, prefix[0], ""})
return err
}

func (e *ecp) Default(config interface{}) error {
_, err := e.rangeOver(roOption{config, true, "", ""})
return err
}

func (e *ecp) List(config interface{}, prefix ...string) []string {
list := []string{}

if prefix == nil {
prefix = []string{"ECP"}
}
parentName := prefix[0]

configValue := toValue(config)
configType := configValue.Type()
for index := 0; index < configValue.NumField(); index++ {
all := e.getAll(gaOption{configType, configValue, index, parentName})
if all.sName == "-" || all.kName == "" {
continue
}
switch all.rValue.Kind() {
case reflect.Struct:
prefix := e.GetKey(parentName, all.sName, all.rTag)
list = append(list, e.List(all.rValue, prefix)...)
default:
if strings.Contains(all.value, " ") {
all.value = fmt.Sprintf("\"%s\"", all.value)
}
list = append(list, fmt.Sprintf("%s=%s", all.kName, all.value))
}
}

return list
}

// List function will also fill up the value of the environment key
// it the "default" tag has value

// List all the config environments
func List(config interface{}, prefix ...string) []string {
return globalEcp.List(config, prefix...)
}

// Parse the configuration through environments starting with the prefix
// or you can ignore the prefix and the default prefix key will be `ECP`
// ecp.Parse(&config) or ecp.Parse(&config, "PREFIX")
Expand All @@ -22,11 +101,7 @@ import (
// type, thus Parse will only set the default value when the field is
// nil, not the zero value.
func Parse(config interface{}, prefix ...string) error {
if prefix == nil {
prefix = []string{"ECP"}
}
_, err := rangeOver(roOption{config, true, prefix[0], ""})
return err
return globalEcp.Parse(config, prefix...)
}

// the default value of the config is set by a tag named "default"
Expand All @@ -48,40 +123,5 @@ func Parse(config interface{}, prefix ...string) error {
// Default set config with its default value
// DEPRECATED: just use `Parse`
func Default(config interface{}) error {
_, err := rangeOver(roOption{config, true, "", ""})
return err
}

// List function will also fill up the value of the environment key
// it the "default" tag has value

// List all the config environments
func List(config interface{}, prefix ...string) []string {
list := []string{}

if prefix == nil {
prefix = []string{"ECP"}
}
parentName := prefix[0]

configValue := toValue(config)
configType := configValue.Type()
for index := 0; index < configValue.NumField(); index++ {
all := getAll(gaOption{configType, configValue, index, parentName})
if all.sName == "-" || all.kName == "" {
continue
}
switch all.rValue.Kind() {
case reflect.Struct:
prefix := GetKey(parentName, all.sName, all.rTag)
list = append(list, List(all.rValue, prefix)...)
default:
if strings.Contains(all.value, " ") {
all.value = fmt.Sprintf("\"%s\"", all.value)
}
list = append(list, fmt.Sprintf("%s=%s", all.kName, all.value))
}
}

return list
return globalEcp.Default(config)
}
12 changes: 6 additions & 6 deletions ecp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ func TestList(t *testing.T) {
})

t.Run("with get key", func(t *testing.T) {
GetKey = func(parentName, structName string, tag reflect.StructTag) (key string) {
globalEcp.GetKey = func(parentName, structName string, tag reflect.StructTag) (key string) {
return strings.ToLower(parentName) + "." + strings.ToLower(structName)
}
list := List(config)
Expand All @@ -132,7 +132,7 @@ func TestList(t *testing.T) {
}

// reset get key function
GetKey = getKeyFromEnv
globalEcp.GetKey = getKeyFromEnv
})
}

Expand Down Expand Up @@ -259,14 +259,14 @@ func TestDefault(t *testing.T) {
func TestGetKeyLookupValue(t *testing.T) {
config := configType{}

GetKey = func(parentName, structName string, tag reflect.StructTag) (key string) {
globalEcp.GetKey = func(parentName, structName string, tag reflect.StructTag) (key string) {
return parentName + "." + structName
}
defer func() {
GetKey = getKeyFromEnv
globalEcp.GetKey = getKeyFromEnv
}()

LookupValue = func(field reflect.Value, key string) (value string, exist bool) {
globalEcp.LookupValue = func(field reflect.Value, key string) (value string, exist bool) {
switch field.Kind() {
case reflect.String:
return "string", true
Expand Down Expand Up @@ -304,7 +304,7 @@ func TestIgnoreFunc(t *testing.T) {
}

config2 := configType{}
IgnoreKey = func(field reflect.Value, key string) bool {
globalEcp.IgnoreKey = func(field reflect.Value, key string) bool {
switch field.Kind() {
case reflect.Int64, reflect.Int, reflect.Uint:
case reflect.String:
Expand Down
54 changes: 37 additions & 17 deletions get.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import (
"reflect"
)

func getValue(config interface{}, keyName string) (reflect.Value, error) {
v, err := rangeOver(roOption{config, false, "", keyName})
func (e *ecp) getValue(config interface{}, keyName string) (reflect.Value, error) {
v, err := e.rangeOver(roOption{config, false, "", keyName})
if err != nil {
return reflect.Value{}, err
}
Expand All @@ -17,19 +17,17 @@ func getValue(config interface{}, keyName string) (reflect.Value, error) {
return v, err
}

// Get the value of the keyName in that struct
func Get(config interface{}, keyName string) (interface{}, error) {
v, err := getValue(config, keyName)
func (e *ecp) Get(config interface{}, keyName string) (interface{}, error) {
v, err := e.getValue(config, keyName)
if err != nil {
return nil, err
}

return v.Interface(), nil
}

// GetBool returns bool
func GetBool(config interface{}, keyName string) (bool, error) {
v, err := getValue(config, keyName)
func (e *ecp) GetBool(config interface{}, keyName string) (bool, error) {
v, err := e.getValue(config, keyName)
if err != nil {
return false, err
}
Expand All @@ -40,9 +38,8 @@ func GetBool(config interface{}, keyName string) (bool, error) {
return false, fmt.Errorf("value is not bool, it's %s", v.Kind())
}

// GetInt64 returns int64
func GetInt64(config interface{}, keyName string) (int64, error) {
v, err := getValue(config, keyName)
func (e *ecp) GetInt64(config interface{}, keyName string) (int64, error) {
v, err := e.getValue(config, keyName)
if err != nil {
return -1, err
}
Expand All @@ -63,9 +60,8 @@ func GetInt64(config interface{}, keyName string) (int64, error) {
return -1, fmt.Errorf("value is %s", v.Kind())
}

// GetString returns string
func GetString(config interface{}, keyName string) (string, error) {
v, err := getValue(config, keyName)
func (e *ecp) GetString(config interface{}, keyName string) (string, error) {
v, err := e.getValue(config, keyName)
if err != nil {
return "", err
}
Expand All @@ -76,9 +72,8 @@ func GetString(config interface{}, keyName string) (string, error) {
return "", fmt.Errorf("value is not string, it's %s", v.Kind())
}

// GetFloat64 returns float64
func GetFloat64(config interface{}, keyName string) (float64, error) {
v, err := getValue(config, keyName)
func (e *ecp) GetFloat64(config interface{}, keyName string) (float64, error) {
v, err := e.getValue(config, keyName)
if err != nil {
return -1, err
}
Expand All @@ -91,3 +86,28 @@ func GetFloat64(config interface{}, keyName string) (float64, error) {
}
return -1, fmt.Errorf("value is %s", v.Kind())
}

// Get the value of the keyName in that struct
func Get(config interface{}, keyName string) (interface{}, error) {
return globalEcp.Get(config, keyName)
}

// GetBool returns bool
func GetBool(config interface{}, keyName string) (bool, error) {
return globalEcp.GetBool(config, keyName)
}

// GetInt64 returns int64
func GetInt64(config interface{}, keyName string) (int64, error) {
return globalEcp.GetInt64(config, keyName)
}

// GetString returns string
func GetString(config interface{}, keyName string) (string, error) {
return globalEcp.GetString(config, keyName)
}

// GetFloat64 returns float64
func GetFloat64(config interface{}, keyName string) (float64, error) {
return globalEcp.GetFloat64(config, keyName)
}
45 changes: 0 additions & 45 deletions init.go

This file was deleted.

8 changes: 4 additions & 4 deletions parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (

// parseSlice support slice of string, int, int8, int16, int32, int64
// float32, float64, uint, uint8, uint16, uint32, uint64, bool
func parseSlice(v string, field reflect.Value) error {
func (e *ecp) parseSlice(v string, field reflect.Value) error {
if v == "" {
return nil
}
Expand All @@ -23,7 +23,7 @@ func parseSlice(v string, field reflect.Value) error {

// either space nor commas is perfect, but I think space is better
// since it's more natural: fmt.Println([]int{1, 2, 3}) = [1 2 3]
stringSlice := strings.Split(v, " ") // split by space
stringSlice := strings.Split(v, e.SplitChar) // split by space

field.Set(reflect.MakeSlice(field.Type(), len(stringSlice), cap(stringSlice)))

Expand Down Expand Up @@ -183,7 +183,7 @@ func parseSlice(v string, field reflect.Value) error {
return nil
}

func parsePointer(typ reflect.Type, value string) (interface{}, error) {
func (e *ecp) parsePointer(typ reflect.Type, value string) (interface{}, error) {
var rValue interface{}
switch typ.Kind() {
case reflect.String:
Expand Down Expand Up @@ -259,7 +259,7 @@ func parsePointer(typ reflect.Type, value string) (interface{}, error) {

case reflect.Slice:
newValue := reflect.New(typ)
if err := parseSlice(value, newValue); err != nil {
if err := e.parseSlice(value, newValue); err != nil {
return rValue, err
}
rValue = newValue
Expand Down
2 changes: 2 additions & 0 deletions parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ func TestParseSlice(t *testing.T) {
NotSlice string
}

var parseSlice = globalEcp.parseSlice

s := &slices{}

t.Run("test string", func(t *testing.T) {
Expand Down
Loading

0 comments on commit 73601f1

Please sign in to comment.