add map support
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
This commit is contained in:
parent
19fefe591c
commit
2868c39a87
27
env.go
27
env.go
@ -43,9 +43,28 @@ func (c *envConfig) Load(ctx context.Context) error {
|
|||||||
|
|
||||||
func (c *envConfig) fillValue(ctx context.Context, value reflect.Value, val string) error {
|
func (c *envConfig) fillValue(ctx context.Context, value reflect.Value, val string) error {
|
||||||
switch value.Kind() {
|
switch value.Kind() {
|
||||||
|
case reflect.Map:
|
||||||
|
t := value.Type()
|
||||||
|
nvals := strings.FieldsFunc(val, func(c rune) bool { return c == ',' || c == ';' })
|
||||||
|
if value.IsNil() {
|
||||||
|
value.Set(reflect.MakeMapWithSize(t, len(nvals)))
|
||||||
|
}
|
||||||
|
kt := t.Key()
|
||||||
|
et := t.Elem()
|
||||||
|
for _, nval := range nvals {
|
||||||
|
kv := strings.FieldsFunc(nval, func(c rune) bool { return c == '=' })
|
||||||
|
mkey := reflect.Indirect(reflect.New(kt))
|
||||||
|
mval := reflect.Indirect(reflect.New(et))
|
||||||
|
if err := c.fillValue(ctx, mkey, kv[0]); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := c.fillValue(ctx, mval, kv[1]); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
value.SetMapIndex(mkey, mval)
|
||||||
|
}
|
||||||
case reflect.Slice, reflect.Array:
|
case reflect.Slice, reflect.Array:
|
||||||
nvals := strings.FieldsFunc(val, func(c rune) bool { return c == ',' || c == ';' })
|
nvals := strings.FieldsFunc(val, func(c rune) bool { return c == ',' || c == ';' })
|
||||||
// value = value.Elem()
|
|
||||||
value.Set(reflect.MakeSlice(reflect.SliceOf(value.Type().Elem()), len(nvals), len(nvals)))
|
value.Set(reflect.MakeSlice(reflect.SliceOf(value.Type().Elem()), len(nvals), len(nvals)))
|
||||||
for idx, nval := range nvals {
|
for idx, nval := range nvals {
|
||||||
nvalue := reflect.Indirect(reflect.New(value.Type().Elem()))
|
nvalue := reflect.Indirect(reflect.New(value.Type().Elem()))
|
||||||
@ -53,7 +72,6 @@ func (c *envConfig) fillValue(ctx context.Context, value reflect.Value, val stri
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
value.Index(idx).Set(nvalue)
|
value.Index(idx).Set(nvalue)
|
||||||
//value.Set(reflect.Append(value, nvalue))
|
|
||||||
}
|
}
|
||||||
case reflect.Bool:
|
case reflect.Bool:
|
||||||
v, err := strconv.ParseBool(val)
|
v, err := strconv.ParseBool(val)
|
||||||
@ -145,7 +163,7 @@ func (c *envConfig) fillValues(ctx context.Context, valueOf reflect.Value) error
|
|||||||
if valueOf.Kind() == reflect.Ptr {
|
if valueOf.Kind() == reflect.Ptr {
|
||||||
values = valueOf.Elem()
|
values = valueOf.Elem()
|
||||||
} else {
|
} else {
|
||||||
values = valueOf
|
values = valueOf
|
||||||
}
|
}
|
||||||
|
|
||||||
if values.Kind() == reflect.Invalid {
|
if values.Kind() == reflect.Invalid {
|
||||||
@ -167,7 +185,8 @@ func (c *envConfig) fillValues(ctx context.Context, valueOf reflect.Value) error
|
|||||||
if len(field.PkgPath) != 0 {
|
if len(field.PkgPath) != 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if value.Kind() == reflect.Ptr {
|
switch value.Kind() {
|
||||||
|
case reflect.Ptr :
|
||||||
if value.IsNil() {
|
if value.IsNil() {
|
||||||
if value.Type().Elem().Kind() != reflect.Struct {
|
if value.Type().Elem().Kind() != reflect.Struct {
|
||||||
// nil pointer to a non-struct: leave it alone
|
// nil pointer to a non-struct: leave it alone
|
||||||
|
@ -14,6 +14,7 @@ type Config struct {
|
|||||||
BoolValue bool `env:"BOOL_VALUE"`
|
BoolValue bool `env:"BOOL_VALUE"`
|
||||||
StringSlice []string `env:"STRING_SLICE"`
|
StringSlice []string `env:"STRING_SLICE"`
|
||||||
IntSlice []int `env:"INT_SLICE"`
|
IntSlice []int `env:"INT_SLICE"`
|
||||||
|
MapStringValue map[string]string `env:"MAP_STRING"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEnv(t *testing.T) {
|
func TestEnv(t *testing.T) {
|
||||||
@ -38,6 +39,7 @@ func TestEnv(t *testing.T) {
|
|||||||
os.Setenv("BOOL_VALUE","true")
|
os.Setenv("BOOL_VALUE","true")
|
||||||
os.Setenv("STRING_SLICE", "STRING_SLICE1,STRING_SLICE2;STRING_SLICE3")
|
os.Setenv("STRING_SLICE", "STRING_SLICE1,STRING_SLICE2;STRING_SLICE3")
|
||||||
os.Setenv("INT_SLICE", "1,2,3,4,5")
|
os.Setenv("INT_SLICE", "1,2,3,4,5")
|
||||||
|
os.Setenv("MAP_STRING", "key1=val1,key2=val2")
|
||||||
|
|
||||||
if err := cfg.Load(ctx); err !=nil {
|
if err := cfg.Load(ctx); err !=nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user