From 26ecbb006d882c4bfd068f2f2cde5b493655a534 Mon Sep 17 00:00:00 2001 From: Tai Groot Date: Thu, 2 Nov 2023 19:09:55 -0700 Subject: [PATCH] add type coercions --- env.go | 138 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) diff --git a/env.go b/env.go index 7d9dcea..dd740b0 100644 --- a/env.go +++ b/env.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "os" + "strconv" "strings" "sync" "time" @@ -27,6 +28,7 @@ type ConfigMap struct { } type ConfigManager struct { + configName string configFileUsed string configType configType envPrefix string @@ -57,10 +59,14 @@ func NewConfigManager(automaticEnv bool) *ConfigManager { } func (c *ConfigManager) ConfigFileUsed() string { + c.mutex.RLock() + defer c.mutex.RUnlock() return c.configFileUsed } func (c *ConfigManager) UseExplicitDefaults(enable bool) { + c.mutex.Lock() + defer c.mutex.Unlock() c.explicitDefaults = enable } @@ -116,21 +122,137 @@ func (c *ConfigManager) WriteConfig() error { } func (c *ConfigManager) GetBool(key string) bool { + c.mutex.RLock() + defer c.mutex.RUnlock() + if v, ok := c.combinedConfig[strings.ToLower(key)]; ok { + val := v.Value + switch val := val.(type) { + case bool: + return val + case string: + if strings.ToLower(val) == "true" { + return true + } + return false + case int: + if val == 0 { + return false + } + return true + case float32, float64: + if val == 0 { + return false + } + return true + case nil: + return false + case time.Duration: + if val == 0 || val < 0 { + return false + } + return true + default: + return val.(bool) + } + } + return false } func (c *ConfigManager) GetDuration(key string) time.Duration { + c.mutex.RLock() + defer c.mutex.RUnlock() + if v, ok := c.combinedConfig[strings.ToLower(key)]; ok { + val := v.Value + switch val := val.(type) { + case time.Duration: + return val + case string: + d, err := time.ParseDuration(val) + if err != nil { + return 0 + } + return d + case int: + return time.Duration(val) + case float32: + return time.Duration(val) + case float64: + return time.Duration(val) + case nil: + return 0 + default: + return val.(time.Duration) + } + } + return 0 } func (c *ConfigManager) GetString(key string) string { + c.mutex.RLock() + defer c.mutex.RUnlock() + if v, ok := c.combinedConfig[strings.ToLower(key)]; ok { + switch val := v.Value.(type) { + case string: + return val + default: + return fmt.Sprintf("%v", v.Value) + } + } + return "" } func (c *ConfigManager) GetStringMap(key string) map[string]any { + c.mutex.RLock() + defer c.mutex.RUnlock() + if v, ok := c.combinedConfig[strings.ToLower(key)]; ok { + switch val := v.Value.(type) { + case map[string]any: + return val + default: + return nil + } + } + return nil } func (c *ConfigManager) GetStringSlice(key string) []string { + c.mutex.RLock() + defer c.mutex.RUnlock() + if v, ok := c.combinedConfig[strings.ToLower(key)]; ok { + switch val := v.Value.(type) { + case []string: + return val + default: + return nil + } + } + return nil } func (c *ConfigManager) GetInt(key string) int { + c.mutex.RLock() + defer c.mutex.RUnlock() + if v, ok := c.combinedConfig[strings.ToLower(key)]; ok { + switch val := v.Value.(type) { + case int: + return val + case string: + i, err := strconv.Atoi(val) + if err != nil { + return 0 + } + return i + case float32: + return int(val) + case float64: + return int(val) + case nil: + return 0 + default: + return val.(int) + } + } + return 0 } func (c *ConfigManager) SetConfigType(configType string) error { @@ -166,6 +288,17 @@ func (c *ConfigManager) SetDefault(key string, value any) { } func (c *ConfigManager) GetIntSlice(key string) []int { + c.mutex.RLock() + defer c.mutex.RUnlock() + if v, ok := c.combinedConfig[strings.ToLower(key)]; ok { + switch val := v.Value.(type) { + case []int: + return val + default: + return nil + } + } + return nil } func (c *ConfigManager) ReadInConfig() error { @@ -214,8 +347,13 @@ func readFile(filename string, fileType configType) (map[string]any, error) { } func (c *ConfigManager) SetConfigName(name string) { + c.mutex.Lock() + defer c.mutex.Unlock() + c.configName = name } func (c *ConfigManager) SetConfigFile(file string) { + c.mutex.Lock() + defer c.mutex.Unlock() c.configFileUsed = file }