A currency code is a standardized three-letter identifier for a currency, such as USD or EUR. In a money package, it identifies the currency attached to an amount and remains hidden inside an immutable value object. section 6.1.1
A practical currency-code implementation:
- Represent the code with a private string field so external users cannot mutate it directly. section 6.1.1
- Parse input through ParseCurrency, rejecting values that are not exactly three letters. section 6.2.5
- Associate each supported code with decimal precision, using explicit cases and a two-digit default for most currencies. section 6.2.5
- Expose ErrInvalidCurrencyCode so callers can distinguish invalid input from other errors. section 6.2.5
Parsing and testing currency codes
ParseCurrency("EUR") returns a Currency with precision 2; BHD uses precision 3, VND precision 1, and IRR precision 0. Table-driven tests run successful and invalid cases separately with t.Run.
Listing 6.13 currency.go: Function for supported currencies
// ErrInvalidCurrencyCode is returned when the currency
// to parse is not a standard 3-letter code.
const ErrInvalidCurrencyCode =
Error("invalid currency code") #1
// ParseCurrency returns the currency associated to
// a name and may return ErrInvalidCurrencyCode.
func ParseCurrency(code string) (Currency, error) {
if len(code) != 3 { #2
return Currency{}, ErrInvalidCurrencyCode
}
switch code {
case "IRR":
return Currency{code: code, precision: 0}, nil
case "CNY", "VND": #3
return Currency{code: code, precision: 1}, nil
case "BHD", "IQD", "KWD", "LYD", "OMR", "TND": #3
return Currency{code: code, precision: 3}, nil
default:
return Currency{code: code, precision: 2}, nil #4
}
}
Inspect the parser implementation, including length validation, explicit precision mappings, and the default precision path. section 6.2.5
