diff --git a/datatype.go b/datatype.go new file mode 100644 index 0000000..bd53649 --- /dev/null +++ b/datatype.go @@ -0,0 +1,23 @@ +package envconf +type DataType int +const ( + TypeNone DataType = iota + TypeInt DataType = iota + TypeDuration DataType = iota + TypeString DataType = iota + TypeBool DataType = iota +) + +func (dtype DataType) String()(string) { + types := make(map[DataType]string) + types[TypeNone] = "none" + types[TypeInt] = "int" + types[TypeDuration] = "duration" + types[TypeString] = "string" + types[TypeBool] = "bool" + str, ok := types[dtype] + if ok { + return str + } + return "invalid" +} diff --git a/main.go b/main.go index f27b2c8..710ad8f 100644 --- a/main.go +++ b/main.go @@ -2,36 +2,35 @@ package envconf import ("strings" "unicode" + "strconv" + "time" + "errors" + "fmt" "os") -type DataType int - -const ( - TypeNone DataType = iota - TypeUnset DataType = iota - TypeInt DataType = iota - TypeDuration DataType = iota - TypeString DataType = iota -) - type cEntry struct { value string + parsed cValue dtype DataType + unset bool + empty bool +} + +type cValue struct { + intval int64 + durval time.Duration + strval string + err error } type Config struct { + parsed bool env map[string]cEntry } -func getFirstRune(str string)(rune) { - for _,v := range str { - return v - } - return rune(0) -} - 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) @@ -41,6 +40,8 @@ func NewConfig()(*Config) { var entry cEntry entry.value = splitted[1] entry.dtype = TypeNone + entry.unset = false + entry.empty = false config.env[key] = entry } } @@ -54,7 +55,64 @@ func (c *Config) Define(key string, dtype DataType) { entry.dtype = dtype } else { var entry cEntry - entry.dtype = TypeUnset + entry.dtype = dtype + entry.unset = true + entry.empty = true c.env[key] = entry } } + +func (c *Config) DefineDefault(key string, val string, dtype DataType) { + entry, ok := c.env[key] + if ok { + if entry.unset { + entry.empty = false + entry.value = val + entry.dtype = dtype + } + } else { + var entry cEntry + entry.dtype = dtype + entry.unset = true + entry.empty = false + c.env[key] = entry + } +} + +func (c *Config) Parse() { + parsers := make(map[DataType](func(string)(cValue))) + parsers[TypeInt] = parseInt + parsers[TypeDuration] = parseDuration + + for k,v := range c.env { + parser, ok := parsers[v.dtype] + if ok { + 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)) + } + } else { + v.parsed = parser(v.value) + } + } + } +} + +func parseInt(str string)(ret cValue) { + ret.intval, ret.err = strconv.ParseInt(str, 10, 64) + return +} + +func parseDuration(str string)(ret cValue) { + ret.durval, ret.err = time.ParseDuration(str) + return +} + +func getFirstRune(str string)(rune) { + for _,v := range str { + return v + } + return rune(0) +} + +