Skip to content

Commit

Permalink
Support UnmarshalCSVWithFields in readEach
Browse files Browse the repository at this point in the history
- Slight rearrangment compared to readTo to place it above the fieldInfo check; if a type is going to completely handle unmarshalling by implementing this interface, we shouldn't care that it has matching csv tagged fields or not
- Also add missing default value setting in readEach
  • Loading branch information
mschmidt-onecause committed May 20, 2024
1 parent b87c2d0 commit be33749
Showing 1 changed file with 35 additions and 1 deletion.
36 changes: 35 additions & 1 deletion decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -289,8 +289,13 @@ func readEach(decoder SimpleDecoder, errHandler ErrorHandler, c interface{}) err
return err
}
}

var withFieldsOK bool
var fieldTypeUnmarshallerWithKeys TypeUnmarshalCSVWithFields

i := 0
for {
objectIface := reflect.New(outValue.Type().Elem()).Interface()
line, err := decoder.GetCSVRow()
if err == io.EOF {
break
Expand All @@ -299,8 +304,31 @@ func readEach(decoder SimpleDecoder, errHandler ErrorHandler, c interface{}) err
}
outInner := createNewOutInner(outInnerWasPointer, outInnerType)
for j, csvColumnContent := range line {

if outInner.CanInterface() {
fieldTypeUnmarshallerWithKeys, withFieldsOK = objectIface.(TypeUnmarshalCSVWithFields)
if withFieldsOK {
if err := fieldTypeUnmarshallerWithKeys.UnmarshalCSVWithFields(headers[j], csvColumnContent); err != nil {
parseError := csv.ParseError{
Line: i + 2, //add 2 to account for the header & 0-indexing of arrays
Column: j + 1,
Err: err,
}
return &parseError
}

continue
}
}

if fieldInfo, ok := csvHeadersLabels[j]; ok { // Position found accordingly to header name
if err := setInnerField(&outInner, outInnerWasPointer, fieldInfo.IndexChain, csvColumnContent, fieldInfo.omitEmpty); err != nil { // Set field of struct

value := csvColumnContent
if value == "" {
value = fieldInfo.defaultValue
}

if err := setInnerField(&outInner, outInnerWasPointer, fieldInfo.IndexChain, value, fieldInfo.omitEmpty); err != nil { // Set field of struct
parseError := &csv.ParseError{
Line: i + 2, //add 2 to account for the header & 0-indexing of arrays
Column: j + 1,
Expand All @@ -313,6 +341,12 @@ func readEach(decoder SimpleDecoder, errHandler ErrorHandler, c interface{}) err
}
}
}

if withFieldsOK {
reflectedObject := reflect.ValueOf(objectIface)
outInner = reflectedObject.Elem()
}

outValue.Send(outInner)
i++
}
Expand Down

0 comments on commit be33749

Please sign in to comment.