Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,17 @@ func main() {
```


This library uses runtime reflection just like `encoding/json`. Most programs won't have more than a handful of config objects, so the slowness typically associated with reflection is negligible here.
This library uses runtime reflection just like `encoding/json`. Most programs won't have more than a handful of config objects, so the slowness typically associated with reflection is negligible here.

### Supported types

Four types are currently supported:
Four types are currently supported:

* `string` - defaults to `""`
* `int` - defaults to `0`
* `bool` - defaults to `false`
* `float64` - defaults to `0.0`
* `float64` - defaults to `0.0`
* `time.Duration` - defaults to `0`

Support for custom types via interfaces will likely make an an appearance at a later date.

Expand Down Expand Up @@ -85,7 +86,7 @@ type Config struct {

#### `default`

If specified, the default will be used if no environment variable is found matching the key. Default values must be castable to the associated struct field type, otherwise an error is returned.
If specified, the default will be used if no environment variable is found matching the key. Default values must be castable to the associated struct field type, otherwise an error is returned.

```go
// Look for a variable `ENABLED` or otherwise default to true
Expand All @@ -108,7 +109,7 @@ config := &Config{}
fmt.Println(config.Name) // prints "Inigo"
```

#### `options`
#### `options`

Options ensure that an environment variable is in a set of possible valid values. If it is not, an error is returned.

Expand Down
20 changes: 20 additions & 0 deletions env_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package env

import (
"testing"
"time"
)

func TestParseDuration(t *testing.T) {
var cfg = struct {
Duration time.Duration `env:"key=DURATION default=5s"`
}{}

if err := Process(&cfg); err != nil {
t.Fatal(err)
}

if cfg.Duration != time.Second*5 {
t.Fatalf("%v != %f ", cfg.Duration, time.Second*5)
}
}
18 changes: 16 additions & 2 deletions var.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
_ "regexp"
"strconv"
"strings"
"time"
)

// Var struct
Expand All @@ -22,11 +23,16 @@ type Var struct {

// NewVar returns a new Var
func NewVar(field reflect.StructField) (*Var, error) {
return NewVarWithFunc(field, os.Getenv)
}

// NewVarWithFunc returns a new Var. get returns the value for the given key
func NewVarWithFunc(field reflect.StructField, get func(string) string) (*Var, error) {
// spew.Dump(new(Var).Default == reflect.ValueOf(nil))
newVar := &Var{} //Default: reflect.ValueOf(nil)}
newVar.Parse(field)

value, err := convert(newVar.Type, os.Getenv(newVar.Key))
value, err := convert(newVar.Type, get(newVar.Key))
if err != nil {
return newVar, err
}
Expand Down Expand Up @@ -168,6 +174,15 @@ func convert(t reflect.Type, value string) (reflect.Value, error) {
return reflect.ValueOf(nil), nil
}

var d time.Duration

switch t {
case reflect.TypeOf(d):
result, err := time.ParseDuration(value)
return reflect.ValueOf(result), err
default:
}

switch t.Kind() {
case reflect.String:
return reflect.ValueOf(value), nil
Expand All @@ -177,7 +192,6 @@ func convert(t reflect.Type, value string) (reflect.Value, error) {
case reflect.Int:
return parseInt(value)
case reflect.Bool:

return parseBool(value)
}

Expand Down