Skip to content

Commit

Permalink
fix: unmarshall slice
Browse files Browse the repository at this point in the history
  • Loading branch information
caarlos0 committed Mar 9, 2019
1 parent 66633e7 commit ba219f0
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 6 deletions.
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@ script:
after_script:
- go get github.com/mattn/goveralls
- goveralls -coverprofile=coverage.out -service=travis-ci -repotoken='eCcizKmTdSaJCz8Ih33WDppdqb9kioYwi'
notifications:
email: false
47 changes: 41 additions & 6 deletions env.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ var (
},
reflect.Uint64: func(v string) (interface{}, error) {
i, err := strconv.ParseUint(v, 10, 64)
return uint64(i), err
return i, err
},
reflect.Uint8: func(v string) (interface{}, error) {
i, err := strconv.ParseUint(v, 10, 8)
Expand Down Expand Up @@ -246,17 +246,26 @@ func handleSlice(field reflect.Value, value, separator string, funcMap CustomPar
if separator == "" {
separator = ","
}
parts := strings.Split(value, separator)
result := reflect.MakeSlice(field.Type(), 0, len(parts))
var parts = strings.Split(value, separator)

parserFunc, ok := funcMap[field.Type().Elem()]
var elemType = field.Type().Elem()
if elemType.Kind() == reflect.Ptr {
elemType = elemType.Elem()
}

if _, ok := reflect.New(elemType).Interface().(encoding.TextUnmarshaler); ok {
return parseTextUnmarshalers(field, parts)
}

parserFunc, ok := funcMap[elemType]
if !ok {
parserFunc, ok = defaultBuiltInParsers[field.Type().Elem().Kind()]
parserFunc, ok = defaultBuiltInParsers[elemType.Kind()]
if !ok {
return fmt.Errorf("no parser for slice of %s", field.Type().Elem().Kind().String())
return fmt.Errorf("no parser for slice of %s", elemType.Kind().String())
}
}

var result = reflect.MakeSlice(field.Type(), 0, len(parts))
for _, part := range parts {
r, err := parserFunc(part)
if err != nil {
Expand Down Expand Up @@ -285,3 +294,29 @@ func handleTextUnmarshaler(field reflect.Value, value string) error {

return tm.UnmarshalText([]byte(value))
}

func parseTextUnmarshalers(field reflect.Value, data []string) error {
s := len(data)
elemType := field.Type().Elem()
slice := reflect.MakeSlice(reflect.SliceOf(elemType), s, s)
for i, v := range data {
sv := slice.Index(i)
kind := sv.Kind()
if kind == reflect.Ptr {
sv = reflect.New(elemType.Elem())
} else {
sv = sv.Addr()
}
tm := sv.Interface().(encoding.TextUnmarshaler)
if err := tm.UnmarshalText([]byte(v)); err != nil {
return err
}
if kind == reflect.Ptr {
slice.Index(i).Set(sv)
}
}

field.Set(slice)

return nil
}
1 change: 1 addition & 0 deletions env_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,7 @@ func TestTypeCustomParserBasicInvalid(t *testing.T) {
assert.EqualError(t, err, "custom parser error: random error")
}

// TODO: this is the only test failing right now, fix it.
func TestCustomParserNotCalledForNonAlias(t *testing.T) {
type T uint64
type U uint64
Expand Down

0 comments on commit ba219f0

Please sign in to comment.