modules/core/config/internal.go

90 lines
2.1 KiB
Go

package config
import (
"errors"
"fmt"
"os"
"reflect"
"strconv"
"strings"
)
func getEnvVar(value reflect.Value, rtype reflect.Type, counter int, prefix string) error {
if value.Kind() != reflect.Ptr {
return errors.New("not a pointer value")
}
f := reflect.StructField{}
if counter != -1 {
f = rtype.Field(counter)
}
value = reflect.Indirect(value)
fName := strings.ToUpper(f.Name)
if prefix != "" {
prefix = strings.TrimLeft(prefix, "_")
}
env := os.Getenv(prefix + fName)
if err := selector(env, &value); err != nil {
return fmt.Errorf("could set value: %w", err)
}
if value.Kind() == reflect.Struct {
for i := 0; i < value.NumField(); i++ {
if err := getEnvVar(value.Field(i).Addr(), value.Type(), i, prefix+fName+"_"); err != nil {
return fmt.Errorf("could not apply env var: %w", err)
}
}
}
return nil
}
func parseToStruct(value reflect.Value, rtype reflect.Type, counter int, prefix string, index map[string]string) error {
if value.Kind() != reflect.Ptr {
return errors.New("not a pointer value")
}
f := reflect.StructField{}
if counter != -1 {
f = rtype.Field(counter)
}
value = reflect.Indirect(value)
fName := strings.ToLower(f.Name)
if prefix != "" {
prefix = strings.TrimLeft(prefix, ".")
}
env := index[prefix+fName]
if err := selector(env, &value); err != nil {
return fmt.Errorf("could set value: %w", err)
}
if value.Kind() == reflect.Struct {
for i := 0; i < value.NumField(); i++ {
if err := parseToStruct(value.Field(i).Addr(), value.Type(), i, prefix+fName+".", index); err != nil {
return fmt.Errorf("could not apply env var: %w", err)
}
}
}
return nil
}
func selector(env string, value *reflect.Value) error {
if env != "" {
//nolint:exhaustive
switch value.Kind() {
case reflect.Int:
envI, err := strconv.Atoi(env)
if err != nil {
return fmt.Errorf("could not parse to int: %w", err)
}
value.SetInt(int64(envI))
case reflect.String:
value.SetString(env)
case reflect.Bool:
envB, err := strconv.ParseBool(env)
if err != nil {
return fmt.Errorf("could not parse bool: %w", err)
}
value.SetBool(envB)
}
}
return nil
}