Skip to content

Instantly share code, notes, and snippets.

@shivam-tripathi
Last active August 29, 2021 14:08
Show Gist options
  • Save shivam-tripathi/f7e3b8cfb0c8bbf1fe9d28253f47ba08 to your computer and use it in GitHub Desktop.
Save shivam-tripathi/f7e3b8cfb0c8bbf1fe9d28253f47ba08 to your computer and use it in GitHub Desktop.
Creates a struct from dotenv file. Has ability to json parse as well in case field is struct and has a key string against it in the env map. Constructs key for a namespace - eg start with "DEV" or "PROD". Input is original type we want to construct, env to store map of key and value (as string) and current active key.
package main
import (
"encoding/json"
"fmt"
"reflect"
"strconv"
"strings"
)
func LoadConfig(_type reflect.Type, env map[string]string, key string) reflect.Value {
switch _type.Kind() {
case reflect.String:
if envValue, ok := env[key]; ok {
logrus.Info("envValue=", envValue, env)
return reflect.ValueOf(&envValue).Elem()
}
panic(fmt.Errorf("Key %s not found %+v", key, env))
case reflect.Int:
fallthrough
case reflect.Int8:
fallthrough
case reflect.Int16:
fallthrough
case reflect.Int32:
fallthrough
case reflect.Int64:
v, err := strconv.Atoi(env[key])
if err != nil {
panic(err)
}
return reflect.ValueOf(&v).Elem()
case reflect.Float32:
fallthrough
case reflect.Float64:
v, err := strconv.ParseFloat(env[key], 10)
if err != nil {
panic(err)
}
return reflect.ValueOf(&v).Elem()
case reflect.Struct:
value := reflect.New(_type).Elem()
if envValue, ok := env[key]; ok {
obj := value.Interface()
err := json.Unmarshal([]byte(envValue), &obj)
if err == nil {
return value
}
}
for i := 0; i < value.NumField(); i++ {
field := value.Field(i)
fieldName := value.Type().Field(i).Name
fieldKey := fmt.Sprintf("%s_%s", key, strings.ToUpper(fieldName))
collected := LoadConfig(field.Type(), env, fieldKey)
field.Set(collected)
}
return value
}
return reflect.ValueOf(nil)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment