Skip to content

Commit

Permalink
Merge pull request #52 from vith/fix-uint64-alias-custom-parser
Browse files Browse the repository at this point in the history
Fix uint64 alias custom parser
  • Loading branch information
caarlos0 authored Oct 20, 2018
2 parents 96ebc20 + 299995a commit 518fcfb
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 10 deletions.
22 changes: 13 additions & 9 deletions env.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,18 @@ func getOr(key, defaultValue string) string {
}

func set(field reflect.Value, refType reflect.StructField, value string, funcMap CustomParsers) error {
// use custom parser if configured for this type
parserFunc, ok := funcMap[refType.Type]
if ok {
val, err := parserFunc(value)
if err != nil {
return fmt.Errorf("Custom parser error: %v", err)
}
field.Set(reflect.ValueOf(val))
return nil
}

// fall back to built-in parsers
switch field.Kind() {
case reflect.Slice:
separator := refType.Tag.Get("envSeparator")
Expand Down Expand Up @@ -215,15 +227,7 @@ func set(field reflect.Value, refType reflect.StructField, value string, funcMap
}
field.SetUint(uintValue)
default:
parserFunc, ok := funcMap[refType.Type]
if !ok {
return handleTextUnmarshaler(field, value)
}
val, err := parserFunc(value)
if err != nil {
return fmt.Errorf("custom parser: %v", err)
}
field.Set(reflect.ValueOf(val))
return handleTextUnmarshaler(field, value)
}
return nil
}
Expand Down
63 changes: 62 additions & 1 deletion env_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"os"
"reflect"
"strconv"
"strings"
"testing"
"time"

Expand Down Expand Up @@ -452,7 +453,7 @@ func TestCustomParserError(t *testing.T) {

assert.Empty(t, cfg.Var.name, "Var.name should not be filled out when parse errors")
assert.Error(t, err)
assert.Equal(t, err.Error(), "custom parser: something broke")
assert.Equal(t, "Custom parser error: something broke", err.Error())
}

func TestCustomParserBasicType(t *testing.T) {
Expand Down Expand Up @@ -483,6 +484,38 @@ func TestCustomParserBasicType(t *testing.T) {
assert.Equal(t, exp, cfg.Const)
}

func TestCustomParserUint64Alias(t *testing.T) {
type T uint64

var one T = 1

type config struct {
Val T `env:"VAL" envDefault:"1x"`
}

parserCalled := false

tParser := func(value string) (interface{}, error) {
parserCalled = true
trimmed := strings.TrimSuffix(value, "x")
i, err := strconv.Atoi(trimmed)
if err != nil {
return nil, err
}
return T(i), nil
}

cfg := config{}

err := env.ParseWithFuncs(&cfg, env.CustomParsers{
reflect.TypeOf(one): tParser,
})

assert.True(t, parserCalled, "tParser should have been called")
assert.NoError(t, err)
assert.Equal(t, T(1), cfg.Val)
}

func TypeCustomParserBasicInvalid(t *testing.T) {
type ConstT int32

Expand All @@ -507,6 +540,34 @@ func TypeCustomParserBasicInvalid(t *testing.T) {
assert.Equal(t, expErr, err)
}

func TestCustomParserNotCalledForNonAlias(t *testing.T) {
type T uint64
type U uint64

type config struct {
Val uint64 `env:"VAL" envDefault:"33"`
Other U `env:"OTHER" envDefault:"44"`
}

tParserCalled := false

tParser := func(value string) (interface{}, error) {
tParserCalled = true
return T(99), nil
}

cfg := config{}

err := env.ParseWithFuncs(&cfg, env.CustomParsers{
reflect.TypeOf(T(0)): tParser,
})

assert.False(t, tParserCalled, "tParser should not have been called")
assert.NoError(t, err)
assert.Equal(t, uint64(33), cfg.Val)
assert.Equal(t, U(44), cfg.Other)
}

func TestCustomParserBasicUnsupported(t *testing.T) {
type ConstT int32

Expand Down

0 comments on commit 518fcfb

Please sign in to comment.