Skip to content

Commit

Permalink
Unmarshaler should be checked before TextUnmarshaler
Browse files Browse the repository at this point in the history
  • Loading branch information
jszwec committed Oct 29, 2017
1 parent e57a468 commit 695b3b2
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 8 deletions.
16 changes: 8 additions & 8 deletions decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (
)

var (
textUnmarshaler = reflect.TypeOf(new(encoding.TextUnmarshaler)).Elem()
fieldUnmarshaler = reflect.TypeOf(new(Unmarshaler)).Elem()
textUnmarshaler = reflect.TypeOf(new(encoding.TextUnmarshaler)).Elem()
csvUnmarshaler = reflect.TypeOf(new(Unmarshaler)).Elem()
)

type decodeFunc func(s string, v reflect.Value) error
Expand Down Expand Up @@ -108,18 +108,18 @@ func decodeInterface(s string, v reflect.Value) error {
}

func decodeFn(typ reflect.Type) (decodeFunc, error) {
if typ.Implements(csvUnmarshaler) {
return decodeFieldUnmarshaler, nil
}
if reflect.PtrTo(typ).Implements(csvUnmarshaler) {
return decodePtrFieldUnmarshaler, nil
}
if typ.Implements(textUnmarshaler) {
return decodeTextUnmarshaler, nil
}
if reflect.PtrTo(typ).Implements(textUnmarshaler) {
return decodePtrTextUnmarshaler, nil
}
if typ.Implements(fieldUnmarshaler) {
return decodeFieldUnmarshaler, nil
}
if reflect.PtrTo(typ).Implements(fieldUnmarshaler) {
return decodePtrFieldUnmarshaler, nil
}

switch typ.Kind() {
case reflect.Ptr:
Expand Down
56 changes: 56 additions & 0 deletions decoder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,47 @@ type TypeI struct {
Int int `csv:"int,omitempty"`
}

type Unmarshalers struct {
CSVUnmarshaler CSVUnmarshaler `csv:"csv"`
PCSVUnmarshaler *CSVUnmarshaler `csv:"pcsv"`
TextUnmarshaler TextUnmarshaler `csv:"text"`
PTextUnmarshaler *TextUnmarshaler `csv:"ptext"`
CSVTextUnmarshaler CSVTextUnmarshaler `csv:"csv-text"`
PCSVTextUnmarshaler *CSVTextUnmarshaler `csv:"pcsv-text"`
}

type CSVUnmarshaler struct {
String string `csv:"string"`
}

func (t *CSVUnmarshaler) UnmarshalCSV(s string) error {
t.String = "unmarshalCSV:" + s
return nil
}

type TextUnmarshaler struct {
String string `csv:"string"`
}

func (t *TextUnmarshaler) UnmarshalText(text []byte) error {
t.String = "unmarshalText:" + string(text)
return nil
}

type CSVTextUnmarshaler struct {
String string `csv:"string"`
}

func (t *CSVTextUnmarshaler) UnmarshalCSV(s string) error {
t.String = "unmarshalCSV:" + s
return nil
}

func (t *CSVTextUnmarshaler) UnmarshalText(text []byte) error {
t.String = "unmarshalText:" + string(text)
return nil
}

type TypeWithInvalidField struct {
String TypeI `csv:"string"`
}
Expand Down Expand Up @@ -290,6 +331,21 @@ string,"{""key"":""value""}"
expectedRecord: []string{"", ""},
header: []string{"String", "int"},
},
{
desc: "decode unmarshalers",
in: "csv,pcsv,text,ptext,csv-text,pcsv-text\nfield,field,field,field,field,field",
out: &Unmarshalers{},
expected: &Unmarshalers{
CSVUnmarshaler: CSVUnmarshaler{"unmarshalCSV:field"},
PCSVUnmarshaler: &CSVUnmarshaler{"unmarshalCSV:field"},
TextUnmarshaler: TextUnmarshaler{"unmarshalText:field"},
PTextUnmarshaler: &TextUnmarshaler{"unmarshalText:field"},
CSVTextUnmarshaler: CSVTextUnmarshaler{"unmarshalCSV:field"},
PCSVTextUnmarshaler: &CSVTextUnmarshaler{"unmarshalCSV:field"},
},
expectedRecord: []string{"field", "field", "field", "field", "field", "field"},
header: []string{"csv", "pcsv", "text", "ptext", "csv-text", "pcsv-text"},
},
{
desc: "custom header",
in: "string,10",
Expand Down

0 comments on commit 695b3b2

Please sign in to comment.