Unmarshaling "" into a *bool should return nil
intentionally-left-nil opened this issue · comments
Given a struct
type struct Row {
Name string `csv:"name",
B *bool `csv:"b",
}
Since B
is a pointer to a bool, it is expected that unmarshaling the a csv that includes the column, but omits the value from the row would unmarshal into a nil ptr. Instead, it unmarshals into &false
Example: gocsv.UnmarshalString("name,b\nhello,", &rows)
expected: rows[0].b == nil
. Actual: rows[0].b == &false
Note that strings work as desired. If you unmarshal into a string pointer, then you would get nil instead.
You can work around this with a custom type but it requires updating the callsites to understand this NullableBool type:
type NullableBool struct {
B *bool
}
func (nb *NullableBool) UnmarshalCSV(val string) error {
// Workaround for https://github.com/gocarina/gocsv/issues/202
// gocsv unmarshals "" into &false, not nil for a *bool
// This is a gocsv bug, but to workaround it, create our own type to emulate
// the same behavior
if val == "" {
return nil
}
var b = []struct {
B *bool `csv:"b"`
}{}
csv := fmt.Sprintf("b\n%s", val)
err := gocsv.UnmarshalString(csv, &b)
if err != nil {
return err
}
nb.B = b[0].B
return nil
}
and then your csv struct would look something like this
type Row struct {
MyBool *NullableBool `csv:"mybool",
}
👍
Indeed, it seems like there could be consensus that pointers should become nil when they are "".