gocarina / gocsv

The GoCSV package aims to provide easy CSV serialization and deserialization to the golang programming language

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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 "".