Skip to content

Commit

Permalink
Merge pull request #2 from axiomzen/add-mapping
Browse files Browse the repository at this point in the history
Add mapping support.
  • Loading branch information
Eliot V Scott authored Jun 19, 2019
2 parents 0a6f755 + 2222b5c commit 55a8560
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 7 deletions.
27 changes: 20 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export MYAPP_USER=Kelsey
export MYAPP_RATE="0.5"
export MYAPP_TIMEOUT="3m"
export MYAPP_USERS="rob,ken,robert"
export MYAPP_COLORCODES="red:1,green:2,blue:3"
```

Write some code:
Expand All @@ -34,16 +35,17 @@ import (
"log"
"time"

"github.com/kelseyhightower/envconfig"
"github.com/axiomzen/envconfig"
)

type Specification struct {
Debug bool
Port int
User string
Users []string
Rate float32
Timeout time.Duration
Debug bool
Port int
User string
Users []string
Rate float32
Timeout time.Duration
ColorCodes map[string]int
}

func main() {
Expand All @@ -62,6 +64,11 @@ func main() {
for _, u := range s.Users {
fmt.Printf(" %s\n", u)
}

fmt.Println("Color codes:")
for k, v := range s.ColorCodes {
fmt.Printf(" %s: %d\n", k, v)
}
}
```

Expand All @@ -77,6 +84,10 @@ Users:
rob
ken
robert
Color codes:
red: 1
green: 2
blue: 3
```

## Struct Tag Support
Expand Down Expand Up @@ -136,6 +147,8 @@ envconfig supports supports these struct field types:
* int8, int16, int32, int64
* bool
* float32, float64
* slices of any supported type
* maps (keys and values of any supported type)

Embedded structs using these fields are also supported.

Expand Down
21 changes: 21 additions & 0 deletions envconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,27 @@ func processField(value string, field reflect.Value) error {
}
}
field.Set(sl)
case reflect.Map:
pairs := strings.Split(value, ",")
mp := reflect.MakeMap(typ)
for _, pair := range pairs {
kvpair := strings.Split(pair, ":")
if len(kvpair) != 2 {
return fmt.Errorf("invalid map item: %q", pair)
}
k := reflect.New(typ.Key()).Elem()
err := processField(kvpair[0], k)
if err != nil {
return err
}
v := reflect.New(typ.Elem()).Elem()
err = processField(kvpair[1], v)
if err != nil {
return err
}
mp.SetMapIndex(k, v)
}
field.Set(mp)
}

return nil
Expand Down
17 changes: 17 additions & 0 deletions envconfig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type Specification struct {
Timeout time.Duration //10
AdminUsers []string
MagicNumbers []int
ColorCodes map[string]int
MultiWordVar string
SomePointer *string
SomePointerWithDefault *string `default:"foo2baz"` //15
Expand Down Expand Up @@ -65,6 +66,7 @@ func TestProcess(t *testing.T) {
os.Setenv("ENV_CONFIG_TIMEOUT", "2m")
os.Setenv("ENV_CONFIG_ADMINUSERS", "John,Adam,Will")
os.Setenv("ENV_CONFIG_MAGICNUMBERS", "5,10,20")
os.Setenv("ENV_CONFIG_COLORCODES", "red:1,green:2,blue:3")
os.Setenv("SERVICE_HOST", "127.0.0.1")
os.Setenv("ENV_CONFIG_TTL", "30")
os.Setenv("ENV_CONFIG_REQUIREDVAR", "foo")
Expand Down Expand Up @@ -126,6 +128,21 @@ func TestProcess(t *testing.T) {
t.Errorf("expected empty string, got %#v", s.Ignored)
}

if len(s.ColorCodes) != 3 ||
s.ColorCodes["red"] != 1 ||
s.ColorCodes["green"] != 2 ||
s.ColorCodes["blue"] != 3 {
t.Errorf(
"expected %#v, got %#v",
map[string]int{
"red": 1,
"green": 2,
"blue": 3,
},
s.ColorCodes,
)
}

if s.DefaultInt != 7 {
t.Errorf("expected %d, got %d", 7, s.DefaultInt)
}
Expand Down

0 comments on commit 55a8560

Please sign in to comment.