bojanz / currency

Currency handling for Go.

Home Page:https://pkg.go.dev/github.com/bojanz/currency

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

allow more uses of the zero value

josharian opened this issue · comments

Hi! Thanks a bunch for this very useful package.

Consider summing a slice of amounts. The natural code to write is something like:

func Sum(amounts []currency.Amount) (currency.Amount, error) {
	var sum currency.Amount
	for _, x := range amounts {
		var err error
		sum, err = sum.Add(x)
		if err != nil {
			return currency.Amount{}, err
		}
	}
	return sum, nil
}

However, this code doesn't work, because sum gets initialized to the zero value, which has an empty currency code. Playground: https://go.dev/play/p/SzMyDcxcos7

I propose that Add and Sub the zero value (0 number, empty currency code) as special, and ignore currency mismatches in this case, adopting the non-empty currency code.

I also hit something similar in currency.Amount.Scan. I want to be able to store the zero value in the database, as a "not yet initialized, unknown currency" value. But loading such a value from the database using currency.Amount.Scan fails, because the empty currency code is not valid. I similarly propose that Scan have a special case for number = 0 and currency code consisting of all spaces ("" or " "), and allow it to be parsed without error.

Thanks again.

Oh, and I should say that I'm happy to send a PR, if this change is welcome.

It is a slight behavioral change, but one that turns an error into a non-error, so it shouldn't cause too many backwards compatibility problems.

Thank you for your feedback, and for validating the approach in advance.

Both suggestions sound reasonable. I suggest doing them in separate PRs (one for Scan, one for the CurrencyMismatch on empty) to simplify merging.

All done. Thank you, and welcome to the contributor list :)