1use crate::*;
4
5
6macro_rules! impl_add_for_primitive {
7 ($t:ty) => {
8 impl_add_for_primitive!(IMPL:ADD $t);
9 impl_add_for_primitive!(IMPL:ADD-ASSIGN $t);
10 impl_add_for_primitive!(IMPL:ADD &$t);
11 impl_add_for_primitive!(IMPL:ADD-ASSIGN &$t);
12 };
13 (IMPL:ADD $t:ty) => {
14 impl Add<$t> for BigDecimal {
15 type Output = BigDecimal;
16
17 fn add(mut self, rhs: $t) -> BigDecimal {
18 self += rhs;
19 self
20 }
21 }
22
23 impl Add<$t> for &BigDecimal {
24 type Output = BigDecimal;
25
26 fn add(self, rhs: $t) -> BigDecimal {
27 self.to_ref() + rhs
28 }
29 }
30
31 impl Add<$t> for BigDecimalRef<'_> {
32 type Output = BigDecimal;
33
34 fn add(self, rhs: $t) -> BigDecimal {
35 BigDecimal::from(rhs) + self
36 }
37 }
38
39 impl Add<BigDecimal> for $t {
40 type Output = BigDecimal;
41
42 fn add(self, rhs: BigDecimal) -> BigDecimal {
43 rhs + self
44 }
45 }
46
47 impl Add<&BigDecimal> for $t {
48 type Output = BigDecimal;
49
50 fn add(self, rhs: &BigDecimal) -> BigDecimal {
51 rhs + self
52 }
53 }
54 };
55 (IMPL:ADD-ASSIGN &$t:ty) => {
56 impl AddAssign<&$t> for BigDecimal {
58 fn add_assign(&mut self, rhs: &$t) {
59 *self += *rhs;
60 }
61 }
62 };
63 (IMPL:ADD-ASSIGN $t:ty) => {
64 impl AddAssign<$t> for BigDecimal {
65 fn add_assign(&mut self, rhs: $t) {
66 if rhs == 0 {
67 } else if self.scale == 0 {
69 self.int_val += rhs;
70 } else {
71 *self += BigDecimal::from(rhs);
72 }
73 }
74 }
75 };
76}
77
78impl_add_for_primitive!(u8);
79impl_add_for_primitive!(u16);
80impl_add_for_primitive!(u32);
81impl_add_for_primitive!(u64);
82impl_add_for_primitive!(u128);
83impl_add_for_primitive!(i8);
84impl_add_for_primitive!(i16);
85impl_add_for_primitive!(i32);
86impl_add_for_primitive!(i64);
87impl_add_for_primitive!(i128);
88
89
90macro_rules! impl_sub_for_primitive {
91 ($t:ty) => {
92 impl_sub_for_primitive!(IMPL:SUB $t);
93 impl_sub_for_primitive!(IMPL:SUB-ASSIGN $t);
94 impl_sub_for_primitive!(IMPL:SUB &$t);
95 impl_sub_for_primitive!(IMPL:SUB-ASSIGN &$t);
96 };
97 (IMPL:SUB $t:ty) => {
98 impl Sub<$t> for BigDecimal {
99 type Output = BigDecimal;
100
101 fn sub(mut self, rhs: $t) -> BigDecimal {
102 self -= rhs;
103 self
104 }
105 }
106
107 impl Sub<$t> for &BigDecimal {
108 type Output = BigDecimal;
109
110 fn sub(self, rhs: $t) -> BigDecimal {
111 let res = BigDecimal::from(rhs).neg();
112 res + self
113 }
114 }
115
116 impl Sub<BigDecimal> for $t {
117 type Output = BigDecimal;
118
119 fn sub(self, rhs: BigDecimal) -> BigDecimal {
120 rhs.neg() + self
121 }
122 }
123
124 impl Sub<&BigDecimal> for $t {
125 type Output = BigDecimal;
126
127 fn sub(self, rhs: &BigDecimal) -> BigDecimal {
128 rhs.neg() + self
129 }
130 }
131 };
132 (IMPL:SUB-ASSIGN &$t:ty) => {
133 impl SubAssign<&$t> for BigDecimal {
134 fn sub_assign(&mut self, rhs: &$t) {
135 *self -= *rhs;
136 }
137 }
138 };
139 (IMPL:SUB-ASSIGN $t:ty) => {
140 impl SubAssign<$t> for BigDecimal {
141 fn sub_assign(&mut self, rhs: $t) {
142 if self.scale == 0 {
143 self.int_val -= rhs;
144 } else {
145 *self -= BigDecimal::from(rhs);
146 }
147 }
148 }
149 };
150}
151
152
153impl_sub_for_primitive!(u8);
154impl_sub_for_primitive!(u16);
155impl_sub_for_primitive!(u32);
156impl_sub_for_primitive!(u64);
157impl_sub_for_primitive!(u128);
158impl_sub_for_primitive!(i8);
159impl_sub_for_primitive!(i16);
160impl_sub_for_primitive!(i32);
161impl_sub_for_primitive!(i64);
162impl_sub_for_primitive!(i128);
163
164
165macro_rules! impl_mul_for_primitive {
166 ($t:ty) => {
167 impl_mul_for_primitive!(IMPL:MUL $t);
168 impl_mul_for_primitive!(IMPL:MUL-ASSIGN $t);
169 impl_mul_for_primitive!(IMPL:MUL &$t);
170 impl_mul_for_primitive!(IMPL:MUL-ASSIGN &$t);
171 };
172 (IMPL:MUL $t:ty) => {
173 impl Mul<$t> for BigDecimal {
174 type Output = BigDecimal;
175
176 fn mul(mut self, rhs: $t) -> BigDecimal {
177 self *= rhs;
178 self
179 }
180 }
181
182 impl Mul<$t> for &BigDecimal {
183 type Output = BigDecimal;
184
185 fn mul(self, rhs: $t) -> BigDecimal {
186 let res = BigDecimal::from(rhs);
187 res * self
188 }
189 }
190
191 impl Mul<BigDecimal> for $t {
192 type Output = BigDecimal;
193
194 fn mul(self, rhs: BigDecimal) -> BigDecimal {
195 rhs * self
196 }
197 }
198
199 impl Mul<&BigDecimal> for $t {
200 type Output = BigDecimal;
201
202 fn mul(self, rhs: &BigDecimal) -> BigDecimal {
203 rhs * self
204 }
205 }
206 };
207 (IMPL:MUL-ASSIGN $t:ty) => {
208 impl MulAssign<$t> for BigDecimal {
209 fn mul_assign(&mut self, rhs: $t) {
210 if rhs.is_zero() {
211 *self = BigDecimal::zero()
212 } else if rhs.is_one() {
213 } else {
215 *self *= BigDecimal::from(rhs);
216 }
217 }
218 }
219 };
220}
221
222
223impl_mul_for_primitive!(u8);
224impl_mul_for_primitive!(u16);
225impl_mul_for_primitive!(u32);
226impl_mul_for_primitive!(u64);
227impl_mul_for_primitive!(u128);
228impl_mul_for_primitive!(i8);
229impl_mul_for_primitive!(i16);
230impl_mul_for_primitive!(i32);
231impl_mul_for_primitive!(i64);
232impl_mul_for_primitive!(i128);
233
234macro_rules! impl_div_for_primitive {
235 (f32) => {
236 impl_div_for_primitive!(IMPL:DIV:FLOAT f32);
237 impl_div_for_primitive!(IMPL:DIV:REF &f32);
238 };
239 (f64) => {
240 impl_div_for_primitive!(IMPL:DIV:FLOAT f64);
241 impl_div_for_primitive!(IMPL:DIV:REF &f64);
242 };
243 ($t:ty) => {
244 impl_div_for_primitive!(IMPL:DIV $t);
245 impl_div_for_primitive!(IMPL:DIV:REF &$t);
246 impl_div_for_primitive!(IMPL:DIV-ASSIGN $t);
247 };
248 (IMPL:DIV $t:ty) => {
249 impl Div<$t> for BigDecimal {
250 type Output = BigDecimal;
251
252 fn div(self, denom: $t) -> BigDecimal {
253 if denom.is_one() {
254 self
255 } else if denom.checked_neg() == Some(1) {
256 self.neg()
257 } else if denom.clone() == 2 {
258 self.half()
259 } else if denom.checked_neg() == Some(2) {
260 self.half().neg()
261 } else {
262 self / BigDecimal::from(denom)
263 }
264 }
265 }
266
267 impl Div<$t> for &BigDecimal {
268 type Output = BigDecimal;
269
270 fn div(self, denom: $t) -> BigDecimal {
271 self.clone() / denom
272 }
273 }
274
275 impl Div<BigDecimal> for $t {
276 type Output = BigDecimal;
277
278 fn div(self, denom: BigDecimal) -> BigDecimal {
279 if self.is_one() {
280 denom.inverse()
281 } else {
282 BigDecimal::from(self) / denom
283 }
284 }
285 }
286
287 impl Div<&BigDecimal> for $t {
288 type Output = BigDecimal;
289
290 fn div(self, denom: &BigDecimal) -> BigDecimal {
291 self / denom.clone()
292 }
293 }
294 };
295 (IMPL:DIV-ASSIGN $t:ty) => {
296 impl DivAssign<$t> for BigDecimal {
297 fn div_assign(&mut self, rhs: $t) {
298 if rhs.is_zero() {
299 *self = BigDecimal::zero()
300 } else if rhs.is_one() {
301 } else {
303 *self = self.clone() / BigDecimal::from(rhs);
304 }
305 }
306 }
307 };
308 (IMPL:DIV:REF $t:ty) => {
309 impl Div<$t> for BigDecimal {
310 type Output = BigDecimal;
311
312 fn div(self, denom: $t) -> BigDecimal {
313 self / *denom
314 }
315 }
316
317 impl Div<BigDecimal> for $t {
318 type Output = BigDecimal;
319
320 fn div(self, denom: BigDecimal) -> Self::Output {
321 *self / denom
322 }
323 }
324
325 impl Div<&BigDecimal> for $t {
326 type Output = BigDecimal;
327
328 fn div(self, denom: &BigDecimal) -> Self::Output {
329 *self / denom
330 }
331 }
332
333 impl DivAssign<$t> for BigDecimal {
334 fn div_assign(&mut self, denom: $t) {
335 self.div_assign(*denom)
336 }
337 }
338 };
339 (IMPL:DIV:FLOAT $t:ty) => {
340 impl Div<$t> for BigDecimal {
341 type Output = BigDecimal;
342
343 #[allow(clippy::float_cmp)]
344 fn div(self, denom: $t) -> BigDecimal {
345 if !denom.is_normal() {
346 BigDecimal::zero()
347 } else if denom == (1.0 as $t) {
348 self
349 } else if denom == (-1.0 as $t) {
350 self.neg()
351 } else if denom == (2.0 as $t) {
352 self.half()
353 } else if denom == (-2.0 as $t) {
354 self.half().neg()
355 } else {
356 self / BigDecimal::try_from(denom).unwrap()
357 }
358 }
359 }
360
361 impl Div<$t> for &BigDecimal {
362 type Output = BigDecimal;
363
364 fn div(self, denom: $t) -> BigDecimal {
365 self.clone() / denom
366 }
367 }
368
369 impl Div<BigDecimal> for $t {
370 type Output = BigDecimal;
371
372 fn div(self, denom: BigDecimal) -> Self::Output {
373 if !self.is_normal() {
374 BigDecimal::zero()
375 } else if self.is_one() {
376 denom.inverse()
377 } else {
378 BigDecimal::try_from(self).unwrap() / denom
379 }
380 }
381 }
382
383 impl Div<&BigDecimal> for $t {
384 type Output = BigDecimal;
385
386 fn div(self, denom: &BigDecimal) -> Self::Output {
387 if !self.is_normal() {
388 BigDecimal::zero()
389 } else if self.is_one() {
390 denom.inverse()
391 } else {
392 BigDecimal::try_from(self).unwrap() / denom
393 }
394 }
395 }
396
397 impl DivAssign<$t> for BigDecimal {
398 fn div_assign(&mut self, denom: $t) {
399 if !denom.is_normal() {
400 *self = BigDecimal::zero()
401 } else {
402 *self = self.clone() / BigDecimal::try_from(denom).unwrap()
403 };
404 }
405 }
406 };
407}
408
409
410impl_div_for_primitive!(u8);
411impl_div_for_primitive!(u16);
412impl_div_for_primitive!(u32);
413impl_div_for_primitive!(u64);
414impl_div_for_primitive!(u128);
415impl_div_for_primitive!(i8);
416impl_div_for_primitive!(i16);
417impl_div_for_primitive!(i32);
418impl_div_for_primitive!(i64);
419impl_div_for_primitive!(i128);
420
421impl_div_for_primitive!(f32);
422impl_div_for_primitive!(f64);
423
424
425impl Neg for BigDecimal {
426 type Output = BigDecimal;
427
428 #[inline]
429 fn neg(mut self) -> BigDecimal {
430 self.int_val = -self.int_val;
431 self
432 }
433}
434
435impl Neg for &BigDecimal {
436 type Output = BigDecimal;
437
438 #[inline]
439 fn neg(self) -> BigDecimal {
440 -self.clone()
441 }
442}
443
444impl Neg for BigDecimalRef<'_> {
445 type Output = Self;
446
447 fn neg(self) -> Self::Output {
448 Self {
449 sign: self.sign.neg(),
450 digits: self.digits,
451 scale: self.scale,
452 }
453 }
454}