Skip to content

Commit

Permalink
Support number/string agnostic JSON decoding (#24)
Browse files Browse the repository at this point in the history
  • Loading branch information
dacohen authored Feb 26, 2023
1 parent be20d5d commit d684e27
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 4 deletions.
14 changes: 10 additions & 4 deletions amount.go
Original file line number Diff line number Diff line change
Expand Up @@ -315,16 +315,22 @@ func (a Amount) MarshalJSON() ([]byte, error) {
// UnmarshalJSON implements the json.Unmarshaler interface.
func (a *Amount) UnmarshalJSON(data []byte) error {
aux := struct {
Number string `json:"number"`
CurrencyCode string `json:"currency"`
Number json.RawMessage `json:"number"`
CurrencyCode string `json:"currency"`
}{}
err := json.Unmarshal(data, &aux)
if err != nil {
return err
}

var auxNumber string
if err = json.Unmarshal(aux.Number, &auxNumber); err != nil {
auxNumber = string(aux.Number)
}

number := apd.Decimal{}
if _, _, err := number.SetString(aux.Number); err != nil {
return InvalidNumberError{aux.Number}
if _, _, err := number.SetString(auxNumber); err != nil {
return InvalidNumberError{auxNumber}
}
if aux.CurrencyCode == "" || !IsValid(aux.CurrencyCode) {
return InvalidCurrencyCodeError{aux.CurrencyCode}
Expand Down
26 changes: 26 additions & 0 deletions amount_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -812,6 +812,32 @@ func TestAmount_UnmarshalJSON(t *testing.T) {
t.Errorf("got %T, want currency.InvalidNumberError", err)
}

d = []byte(`{"number": {"key": "value"}, "currency": "USD"}`)
err = json.Unmarshal(d, unmarshalled)
if e, ok := err.(currency.InvalidNumberError); ok {
if e.Number != `{"key": "value"}` {
t.Errorf(`got %v, "want {"key": "value"}"`, e.Number)
}
wantError := `invalid number "{\"key\": \"value\"}"`
if e.Error() != wantError {
t.Errorf("got %v, want %v", e.Error(), wantError)
}
} else {
t.Errorf("got %T, want currency.InvalidNumberError", err)
}

d = []byte(`{"number":3.45,"currency":"USD"}`)
err = json.Unmarshal(d, unmarshalled)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if unmarshalled.Number() != "3.45" {
t.Errorf("got %v, want 3.45", unmarshalled.Number())
}
if unmarshalled.CurrencyCode() != "USD" {
t.Errorf("got %v, want USD", unmarshalled.CurrencyCode())
}

d = []byte(`{"number":"3.45","currency":"usd"}`)
err = json.Unmarshal(d, unmarshalled)
if e, ok := err.(currency.InvalidCurrencyCodeError); ok {
Expand Down

0 comments on commit d684e27

Please sign in to comment.