package envconf import ("strings" "unicode" "errors" "time" "fmt" "os") type cEntry struct { value string parsed cValue dtype DataType unset bool empty bool } type Config struct { parsed bool env map[string]cEntry } func NewConfig()(*Config) { config := new(Config) config.parsed = false config.env = make(map[string]cEntry) for _,v := range os.Environ() { splitted := strings.SplitN(v, "=", 2) if len(splitted) == 2 { key := strings.TrimSpace(strings.ToUpper(splitted[0])) if unicode.IsLetter(getFirstRune(key)) { var entry cEntry entry.value = splitted[1] entry.dtype = TypeNone entry.unset = false entry.empty = false config.env[key] = entry } } } return config } func (c *Config) Define(key string, dtype DataType) { upper := strings.ToUpper(key) entry, ok := c.env[upper] if ok { entry.dtype = dtype c.env[upper] = entry } else { var entry cEntry entry.dtype = dtype entry.unset = true entry.empty = true c.env[upper] = entry } } func (c *Config) DefineDefault(key string, val string, dtype DataType) { upper := strings.ToUpper(key) entry, ok := c.env[upper] if ok { if entry.unset { entry.value = val } entry.dtype = dtype entry.empty = false c.env[upper] = entry } else { var entry cEntry entry.dtype = dtype entry.unset = true entry.empty = false entry.value = val c.env[upper] = entry } } func (c *Config) Parse() { c.parsed = true for k,v := range c.env { if v.empty { if v.unset { v.parsed.err = errors.New(fmt.Sprintf(`Environment variable "%s" not found. It should have been of type %s.`, k, v.dtype)) c.env[k] = v } } else { v.parsed = v.dtype.parse(k, v.value) c.env[k] = v } } } func (c *Config) Status()(ok bool) { ok = c.parsed if ok { for _,v := range c.env { err := v.parsed.err if err != nil { ok = false fmt.Println(err) } } } return } func (c *Config) GetInt(key string)(int64) { if c.parsed { upper := strings.ToUpper(key) entry, ok := c.env[upper] if ok { return entry.parsed.intval } } return 0 } func (c *Config) GetDirectory(key string)(string) { if c.parsed { upper := strings.ToUpper(key) entry, ok := c.env[upper] if ok { return entry.parsed.strval } } return "" } func (c *Config) GetString(key string)(string) { if c.parsed { upper := strings.ToUpper(key) entry, ok := c.env[upper] if ok { return entry.parsed.strval } } return "" } func (c *Config) GetDuration(key string)(time.Duration) { if c.parsed { upper := strings.ToUpper(key) entry, ok := c.env[upper] if ok { return entry.parsed.durval } } return time.Duration(0) } func (c *Config) GetBool(key string)(bool) { if c.parsed { upper := strings.ToUpper(key) entry, ok := c.env[upper] if ok { return entry.parsed.boolval } } return false } func getFirstRune(str string)(rune) { for _,v := range str { return v } return rune(0) }