@@ -115,103 +115,103 @@ func NewCurrencyValue(amount string, currency CurrencyDefinition) (*CurrencyValu
115
115
}
116
116
117
117
// AmountInt64 returns a valid int64 or an error
118
- func (v * CurrencyValue ) AmountInt64 () (int64 , error ) {
119
- if ! v .Amount .IsInt64 () {
118
+ func (c * CurrencyValue ) AmountInt64 () (int64 , error ) {
119
+ if ! c .Amount .IsInt64 () {
120
120
return 0 , ErrCurrencyValueInsufficientPrecision
121
121
}
122
- return v .Amount .Int64 (), nil
122
+ return c .Amount .Int64 (), nil
123
123
}
124
124
125
125
// AmountUint64 returns a valid int64 or an error
126
- func (v * CurrencyValue ) AmountUint64 () (uint64 , error ) {
127
- if ! v .Amount .IsUint64 () {
126
+ func (c * CurrencyValue ) AmountUint64 () (uint64 , error ) {
127
+ if ! c .Amount .IsUint64 () {
128
128
return 0 , ErrCurrencyValueInsufficientPrecision
129
129
}
130
- return v .Amount .Uint64 (), nil
130
+ return c .Amount .Uint64 (), nil
131
131
}
132
132
133
133
// AmountString returns the string representation of the amount
134
- func (v * CurrencyValue ) AmountString () string {
135
- if v == nil || v .Amount == nil {
134
+ func (c * CurrencyValue ) AmountString () string {
135
+ if c == nil || c .Amount == nil {
136
136
return "0"
137
137
}
138
- return v .Amount .String ()
138
+ return c .Amount .String ()
139
139
}
140
140
141
141
// String returns a string representation of a CurrencyValue
142
- func (v * CurrencyValue ) String () string {
143
- if v == nil {
142
+ func (c * CurrencyValue ) String () string {
143
+ if c == nil {
144
144
return new (CurrencyValue ).String ()
145
145
}
146
- return fmt .Sprintf ("%s %s" , v .Amount .String (), v .Currency .String ())
146
+ return fmt .Sprintf ("%s %s" , c .Amount .String (), c .Currency .String ())
147
147
}
148
148
149
149
// Valid returns an error if the CurrencyValue is invalid
150
- func (v * CurrencyValue ) Valid () error {
151
- if v .Amount == nil {
150
+ func (c * CurrencyValue ) Valid () error {
151
+ if c .Amount == nil {
152
152
return ErrCurrencyValueAmountInvalid
153
153
}
154
- if err := v .Currency .Valid (); err != nil {
154
+ if err := c .Currency .Valid (); err != nil {
155
155
return err
156
156
}
157
157
return nil
158
158
}
159
159
160
160
// Equal indicates if the amount and variety of currency is equivalent
161
- func (v * CurrencyValue ) Equal (other * CurrencyValue ) bool {
162
- if v == nil && other == nil {
161
+ func (c * CurrencyValue ) Equal (other * CurrencyValue ) bool {
162
+ if c == nil && other == nil {
163
163
return true
164
164
}
165
- if v == nil || other == nil {
165
+ if c == nil || other == nil {
166
166
return false
167
167
}
168
- if ! v .Currency .Equal (other .Currency ) {
169
- if v .Currency .Code == other .Currency .Code {
170
- vN , err := v .Normalize ()
168
+ if ! c .Currency .Equal (other .Currency ) {
169
+ if c .Currency .Code == other .Currency .Code {
170
+ cN , err := c .Normalize ()
171
171
if err != nil {
172
172
return false
173
173
}
174
174
oN , err := other .Normalize ()
175
175
if err != nil {
176
176
return false
177
177
}
178
- return vN .Amount .Cmp (oN .Amount ) == 0
178
+ return cN .Amount .Cmp (oN .Amount ) == 0
179
179
}
180
180
return false
181
181
}
182
- return v .Amount .Cmp (other .Amount ) == 0
182
+ return c .Amount .Cmp (other .Amount ) == 0
183
183
}
184
184
185
185
// Normalize updates the CurrencyValue to match the divisibility of the locally defined CurrencyDefinition
186
- func (v * CurrencyValue ) Normalize () (* CurrencyValue , error ) {
187
- localDef , err := AllCurrencies ().Lookup (string (v .Currency .Code ))
186
+ func (c * CurrencyValue ) Normalize () (* CurrencyValue , error ) {
187
+ localDef , err := AllCurrencies ().Lookup (string (c .Currency .Code ))
188
188
if err != nil {
189
189
return nil , err
190
190
}
191
- val , _ , err := v .AdjustDivisibility (localDef .Divisibility )
191
+ val , _ , err := c .AdjustDivisibility (localDef .Divisibility )
192
192
return val , err
193
193
}
194
194
195
195
// AdjustDivisibility updates the Currency.Divisibility and adjusts the Amount to match the new
196
196
// value. An error will be returned if the new divisibility is invalid or produces an unreliable
197
197
// result. This is a helper function which is equivalent to ConvertTo using a copy of the
198
198
// CurrencyDefinition using the updated divisibility and an exchangeRatio of 1.0
199
- func (v * CurrencyValue ) AdjustDivisibility (div uint ) (* CurrencyValue , big.Accuracy , error ) {
200
- if v .Currency .Divisibility == div {
201
- return v , 0 , nil
199
+ func (c * CurrencyValue ) AdjustDivisibility (div uint ) (* CurrencyValue , big.Accuracy , error ) {
200
+ if c .Currency .Divisibility == div {
201
+ return c , 0 , nil
202
202
}
203
- defWithNewDivisibility := v .Currency
203
+ defWithNewDivisibility := c .Currency
204
204
defWithNewDivisibility .Divisibility = div
205
- return v .ConvertTo (defWithNewDivisibility , 1.0 )
205
+ return c .ConvertTo (defWithNewDivisibility , 1.0 )
206
206
}
207
207
208
208
// ConvertTo will perform the following math given its arguments are valid:
209
- // v .Amount * exchangeRatio * (final.Currency.Divisibility/v .Currency.Divisibility)
210
- // where v is the receiver, exchangeRatio is the ratio of (1 final.Currency/v .Currency)
211
- // v and final must both be Valid() and exchangeRatio must not be zero. The accuracy
209
+ // c .Amount * exchangeRatio * (final.Currency.Divisibility/c .Currency.Divisibility)
210
+ // where c is the receiver, exchangeRatio is the ratio of (1 final.Currency/c .Currency)
211
+ // c and final must both be Valid() and exchangeRatio must not be zero. The accuracy
212
212
// indicates if decimal values were trimmed when converting the value back to integer.
213
- func (v * CurrencyValue ) ConvertTo (final CurrencyDefinition , exchangeRatio float64 ) (* CurrencyValue , big.Accuracy , error ) {
214
- if err := v .Valid (); err != nil {
213
+ func (c * CurrencyValue ) ConvertTo (final CurrencyDefinition , exchangeRatio float64 ) (* CurrencyValue , big.Accuracy , error ) {
214
+ if err := c .Valid (); err != nil {
215
215
return nil , 0 , fmt .Errorf ("cannot convert invalid value: %s" , err .Error ())
216
216
}
217
217
if err := final .Valid (); err != nil {
@@ -221,15 +221,15 @@ func (v *CurrencyValue) ConvertTo(final CurrencyDefinition, exchangeRatio float6
221
221
return nil , 0 , ErrCurrencyValueNegativeRate
222
222
}
223
223
224
- amt := new (big.Float ).SetInt (v .Amount )
224
+ amt := new (big.Float ).SetInt (c .Amount )
225
225
exRatio := new (big.Float ).SetFloat64 (exchangeRatio )
226
226
if exRatio == nil {
227
227
return nil , 0 , fmt .Errorf ("exchange ratio (%f) is invalid" , exchangeRatio )
228
228
}
229
229
newAmount := new (big.Float ).SetPrec (53 ).Mul (amt , exRatio )
230
230
231
- if v .Currency .Divisibility != final .Divisibility {
232
- initMagnitude := math .Pow10 (int (v .Currency .Divisibility ))
231
+ if c .Currency .Divisibility != final .Divisibility {
232
+ initMagnitude := math .Pow10 (int (c .Currency .Divisibility ))
233
233
finalMagnitude := math .Pow10 (int (final .Divisibility ))
234
234
divisibilityRatio := new (big.Float ).SetFloat64 (finalMagnitude / initMagnitude )
235
235
newAmount .Mul (newAmount , divisibilityRatio )
@@ -249,23 +249,39 @@ func (v *CurrencyValue) ConvertTo(final CurrencyDefinition, exchangeRatio float6
249
249
250
250
// Cmp exposes the (*big.Int).Cmp behavior after verifying currency and adjusting
251
251
// for different currency divisibilities.
252
- func (v * CurrencyValue ) Cmp (other * CurrencyValue ) (int , error ) {
253
- if v .Currency .Code .String () != other .Currency .Code .String () {
252
+ func (c * CurrencyValue ) Cmp (other * CurrencyValue ) (int , error ) {
253
+ if c .Currency .Code .String () != other .Currency .Code .String () {
254
254
return 0 , ErrCurrencyValueInvalidCmpDifferentCurrencies
255
255
}
256
- if v .Currency .Equal (other .Currency ) {
257
- return v .Amount .Cmp (other .Amount ), nil
256
+ if c .Currency .Equal (other .Currency ) {
257
+ return c .Amount .Cmp (other .Amount ), nil
258
258
}
259
- if v .Currency .Divisibility > other .Currency .Divisibility {
260
- adjOther , _ , err := other .AdjustDivisibility (v .Currency .Divisibility )
259
+ if c .Currency .Divisibility > other .Currency .Divisibility {
260
+ adjOther , _ , err := other .AdjustDivisibility (c .Currency .Divisibility )
261
261
if err != nil {
262
262
return 0 , fmt .Errorf ("adjusting other divisibility: %s" , err .Error ())
263
263
}
264
- return v .Amount .Cmp (adjOther .Amount ), nil
264
+ return c .Amount .Cmp (adjOther .Amount ), nil
265
265
}
266
- selfAdj , _ , err := v .AdjustDivisibility (other .Currency .Divisibility )
266
+ selfAdj , _ , err := c .AdjustDivisibility (other .Currency .Divisibility )
267
267
if err != nil {
268
268
return 0 , fmt .Errorf ("adjusting self divisibility: %s" , err .Error ())
269
269
}
270
270
return selfAdj .Amount .Cmp (other .Amount ), nil
271
271
}
272
+
273
+ // IsZero returns true if Amount is valid and equal to zero
274
+ func (c * CurrencyValue ) IsZero () bool {
275
+ if c .Amount == nil {
276
+ return false
277
+ }
278
+ return c .Amount .Cmp (big .NewInt (0 )) == 0
279
+ }
280
+
281
+ // IsNegative returns true if Amount is valid and less-than zero
282
+ func (c * CurrencyValue ) IsNegative () bool {
283
+ if c .Amount == nil {
284
+ return false
285
+ }
286
+ return c .Amount .Cmp (big .NewInt (0 )) == - 1
287
+ }
0 commit comments