Skip to content

Commit

Permalink
Struct tags - genv (#1)
Browse files Browse the repository at this point in the history
* Parse func - wip

* Parse func - strings only

* Add link to reflect examples

* Update readme

* Add multiple types support

* Add error handling
  • Loading branch information
lalabuy948 authored Aug 18, 2020
1 parent 4dd07c0 commit f74cb63
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 1 deletion.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@

- `IsProduction`, `IsDevelopment` and `IsTesting` checks for `ENVIRONMENT` dot env value.
- `GetEnv` gets env value, fallback as second function argument.
- `Parse` will fill given struct with env values or with fallbacks.
```go
type serverConfig struct {
ServerPort string `genv:"SERVER_PORT,8080"`
MongoUrl string `genv:"MONGO_URL,mongodb://localhost:27017"`
}
```

## Install

Expand Down
55 changes: 54 additions & 1 deletion gonvutils.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
// Package genvutils provides useful environment operations
package genvutils

import "os"
import (
"os"
"reflect"
"strconv"
"strings"
)

//IsProduction checks if ENVIRONMENT value is equal to "PROD".
func IsProduction() bool {
Expand Down Expand Up @@ -61,3 +66,51 @@ func GetEnv(key string, fallback string) string {
}
return fallback
}

//Parse function will parse given pointer to struct and fill it with env values.
//
// type serverConfig struct {
// ServerPort string `genv:"SERVER_PORT,8080"`
// MongoUrl string `genv:"MONGO_URL,mongodb://localhost:27017"`
// }
//
// Here is an example of struct. Good reading about reflect https://github.com/a8m/reflect-examples
func Parse(income interface{}) error {
t := reflect.TypeOf(income).Elem()
v := reflect.ValueOf(income).Elem()

for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
value := v.FieldByName(field.Name)

tag := field.Tag.Get("genv")
tagS := strings.Split(tag, ",")

if value.CanSet() && value.IsValid() {
switch len(tagS) {
case 0:
break
default:
envVarValue := strings.TrimSpace(GetEnv(tagS[0], strings.Join(tagS[1:], ",")))
switch value.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
envVarValueF, _ := strconv.ParseInt(envVarValue, 10, 64)
value.SetInt(envVarValueF)
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
envVarValueF, _ := strconv.ParseUint(envVarValue, 10, 64)
value.SetUint(envVarValueF)
case reflect.Float32, reflect.Float64:
envVarValueF, _ := strconv.ParseFloat(envVarValue, 64)
value.SetFloat(envVarValueF)
case reflect.String:
value.SetString(envVarValue)
case reflect.Bool:
envVarValueF, _ := strconv.ParseBool(envVarValue)
value.SetBool(envVarValueF)
}
}
}
}

return nil
}
55 changes: 55 additions & 0 deletions gonvutils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,3 +142,58 @@ func TestGetEnv(t *testing.T) {

os.Unsetenv("SERVER_PORT")
}

func TestParse(t *testing.T) {

type serverConfig struct {
// simple test
ServerPort string `genv:"SERVER_PORT,8080"`
MongoUrl string `genv:"MONGO_URL,mongodb://localhost:27017"`

// string join test
MongoClusterUrl string `genv:"MONGO_URL,mongodb://mongodb,mongodb1,mongodb2/?replicaSet=rs0"`

// edge cases
RedisUrl string `genv:""`
RedisPort int `genv:"REDIS_PORT, 6371"`
Compress bool `genv:"COMPRES, true"`

// empty
Bla bool
}

var srvConf serverConfig
err := Parse(&srvConf)
if err != nil {
t.Errorf("Parse(&srvConf) | return %v;", err)
}
if srvConf.ServerPort != "8080" {
t.Errorf("Parse(&srvConf) | ServerPort = %v; want 8080", srvConf.ServerPort)
}
if srvConf.MongoUrl != "mongodb://localhost:27017" {
t.Errorf("Parse(&srvConf) | MongoUrl = %v; want mongodb://localhost:27017", srvConf.MongoUrl)
}
if srvConf.RedisPort != 6371 {
t.Errorf("Parse(&srvConf) | RedisPort = %v; want 6371 as int", srvConf.RedisPort)
}
if srvConf.Compress != true {
t.Errorf("Parse(&srvConf) | Compress = %v; want true", srvConf.Compress)
}

os.Setenv("SERVER_PORT", "8181")
os.Setenv("MONGO_URL", "mongodb://localhost:76623")

err = Parse(&srvConf)
if err != nil {
t.Errorf("Parse(&srvConf) | return %v;", err)
}
if srvConf.ServerPort != "8181" {
t.Errorf("Parse(&srvConf) | ServerPort = %v; want 8181", srvConf.ServerPort)
}
if srvConf.MongoUrl != "mongodb://localhost:76623" {
t.Errorf("Parse(&srvConf) | MongoUrl = %v; want mongodb://localhost:76623", srvConf.MongoUrl)
}

os.Unsetenv("SERVER_PORT")
os.Unsetenv("MONGO_URL")
}

0 comments on commit f74cb63

Please sign in to comment.