safe_bigmath/
decimal.rs

1extern crate alloc;
2
3use crate::{SafeInt, parsing::ParsedSafeDec};
4#[cfg(test)]
5use alloc::string::ToString;
6use core::{fmt::Display, ops::*, str::FromStr};
7use quoth::Parsable;
8
9/// Fixed-point decimal built on top of `SafeInt` with `D` fractional digits.
10///
11/// # Examples
12/// ```
13/// use safe_bigmath::SafeDec;
14///
15/// // 3 decimal places
16/// let a: SafeDec<3> = "1.500".parse().unwrap();
17/// let b: SafeDec<3> = "2.250".parse().unwrap();
18/// let c = a + b;
19/// assert_eq!(c.to_string(), "3.750");
20/// ```
21#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
22#[repr(transparent)]
23pub struct SafeDec<const D: usize>(SafeInt);
24
25impl<const D: usize> SafeDec<D> {
26    /// Zero value at the given scale.
27    pub fn zero() -> SafeDec<D> {
28        SafeDec::<D>(SafeInt::zero())
29    }
30
31    fn scale_up(other: &SafeInt) -> SafeInt {
32        other * SafeInt::from(10).pow(D as u32)
33    }
34
35    fn scale_down(other: &SafeInt) -> SafeInt {
36        (other / SafeInt::from(10).pow(D as u32)).unwrap_or(0.into())
37    }
38
39    /// Creates a `SafeDec` from an already scaled integer.
40    ///
41    /// # Examples
42    /// ```
43    /// use safe_bigmath::SafeDec;
44    ///
45    /// let raw = 123_456; // represents 123.456 at 3 decimal places
46    /// let dec = SafeDec::<3>::from_raw(raw);
47    /// assert_eq!(dec.to_string(), "123.456");
48    /// ```
49    pub fn from_raw(raw: impl Into<SafeInt>) -> Self {
50        SafeDec(raw.into())
51    }
52
53    /// Converts between decimal scales, preserving magnitude.
54    ///
55    /// # Examples
56    /// ```
57    /// use safe_bigmath::SafeDec;
58    ///
59    /// let a: SafeDec<4> = "1.2345".parse().unwrap();
60    /// let b = SafeDec::<2>::from_other_scale(a);
61    /// assert_eq!(b.to_string(), "1.24");
62    /// ```
63    pub fn from_other_scale<const D2: usize>(other: SafeDec<D2>) -> Self {
64        if D2 > D {
65            SafeDec((other.0.ceil_div(SafeInt::from(10).pow((D2 - D) as u32))).unwrap())
66        } else {
67            SafeDec(other.0 * SafeInt::from(10).pow((D - D2) as u32))
68        }
69    }
70}
71
72impl<const D: usize> FromStr for SafeDec<D> {
73    type Err = quoth::Error;
74
75    fn from_str(s: &str) -> Result<Self, Self::Err> {
76        let mut stream = quoth::ParseStream::from(s);
77        let parsed = ParsedSafeDec::<D>::parse(&mut stream)?;
78        Ok(SafeDec::<D>(parsed.raw))
79    }
80}
81
82impl<const D: usize> Display for SafeDec<D> {
83    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
84        let ten = SafeInt::from(10);
85        let divisor = ten.clone().pow(D as u32);
86        let abs_value = self.0.clone().abs();
87
88        // These divisions are safe since divisor is never zero
89        let integer_part = (&abs_value / &divisor).unwrap_or(SafeInt::zero());
90        let mut decimal_part = (&abs_value % &divisor).unwrap_or_else(SafeInt::zero);
91
92        if self.0.is_negative() {
93            write!(f, "-")?;
94        }
95
96        write!(f, "{}", integer_part)?;
97        write!(f, ".")?;
98
99        // Extract D decimal digits
100        let mut pow10 = (&divisor / &ten).unwrap(); // guaranteed non-zero
101        for _ in 0..D {
102            let (digit, rem) = decimal_part
103                .div_rem(pow10.clone())
104                .unwrap_or_else(|| (SafeInt::zero(), SafeInt::zero()));
105            write!(f, "{}", digit)?;
106            decimal_part = rem;
107            pow10 = (&pow10 / &ten).unwrap_or(1.into()); // last one goes to 1
108        }
109
110        Ok(())
111    }
112}
113
114impl<const D: usize> Neg for SafeDec<D> {
115    type Output = SafeDec<D>;
116
117    #[inline(always)]
118    fn neg(self) -> SafeDec<D> {
119        SafeDec(-self.0)
120    }
121}
122
123impl<const D: usize> Neg for &SafeDec<D> {
124    type Output = SafeDec<D>;
125
126    #[inline(always)]
127    fn neg(self) -> SafeDec<D> {
128        SafeDec(-self.0.clone())
129    }
130}
131
132macro_rules! impl_decimal_ops_for_primitive {
133    ($prim:ty, rhs_value) => {
134        impl<const D: usize> Add<SafeDec<D>> for $prim {
135            type Output = SafeDec<D>;
136
137            #[inline(always)]
138            fn add(self, other: SafeDec<D>) -> SafeDec<D> {
139                SafeDec(SafeDec::<D>::scale_up(&SafeInt::from(self)).add(other.0))
140            }
141        }
142
143        impl<const D: usize> Sub<SafeDec<D>> for $prim {
144            type Output = SafeDec<D>;
145
146            #[inline(always)]
147            fn sub(self, other: SafeDec<D>) -> SafeDec<D> {
148                SafeDec(SafeDec::<D>::scale_up(&SafeInt::from(self)).sub(other.0))
149            }
150        }
151
152        impl<const D: usize> BitAnd<SafeDec<D>> for $prim {
153            type Output = SafeDec<D>;
154
155            #[inline(always)]
156            fn bitand(self, other: SafeDec<D>) -> SafeDec<D> {
157                SafeDec(SafeDec::<D>::scale_up(&SafeInt::from(self)).bitand(other.0))
158            }
159        }
160
161        impl<const D: usize> BitOr<SafeDec<D>> for $prim {
162            type Output = SafeDec<D>;
163
164            #[inline(always)]
165            fn bitor(self, other: SafeDec<D>) -> SafeDec<D> {
166                SafeDec(SafeDec::<D>::scale_up(&SafeInt::from(self)).bitor(other.0))
167            }
168        }
169
170        impl<const D: usize> BitXor<SafeDec<D>> for $prim {
171            type Output = SafeDec<D>;
172
173            #[inline(always)]
174            fn bitxor(self, other: SafeDec<D>) -> SafeDec<D> {
175                SafeDec(SafeDec::<D>::scale_up(&SafeInt::from(self)).bitxor(other.0))
176            }
177        }
178
179        impl<const D: usize> Mul<SafeDec<D>> for $prim {
180            type Output = SafeDec<D>;
181
182            #[inline(always)]
183            fn mul(self, other: SafeDec<D>) -> SafeDec<D> {
184                SafeDec(SafeInt::from(self).mul(other.0))
185            }
186        }
187    };
188    ($prim:ty, rhs_ref) => {
189        impl<const D: usize> Add<&SafeDec<D>> for $prim {
190            type Output = SafeDec<D>;
191
192            #[inline(always)]
193            fn add(self, other: &SafeDec<D>) -> SafeDec<D> {
194                SafeDec(SafeDec::<D>::scale_up(&SafeInt::from(self)).add(other.0.clone()))
195            }
196        }
197
198        impl<const D: usize> Sub<&SafeDec<D>> for $prim {
199            type Output = SafeDec<D>;
200
201            #[inline(always)]
202            fn sub(self, other: &SafeDec<D>) -> SafeDec<D> {
203                SafeDec(SafeDec::<D>::scale_up(&SafeInt::from(self)).sub(other.0.clone()))
204            }
205        }
206
207        impl<const D: usize> BitAnd<&SafeDec<D>> for $prim {
208            type Output = SafeDec<D>;
209
210            #[inline(always)]
211            fn bitand(self, other: &SafeDec<D>) -> SafeDec<D> {
212                SafeDec(SafeDec::<D>::scale_up(&SafeInt::from(self)).bitand(other.0.clone()))
213            }
214        }
215
216        impl<const D: usize> BitOr<&SafeDec<D>> for $prim {
217            type Output = SafeDec<D>;
218
219            #[inline(always)]
220            fn bitor(self, other: &SafeDec<D>) -> SafeDec<D> {
221                SafeDec(SafeDec::<D>::scale_up(&SafeInt::from(self)).bitor(other.0.clone()))
222            }
223        }
224
225        impl<const D: usize> BitXor<&SafeDec<D>> for $prim {
226            type Output = SafeDec<D>;
227
228            #[inline(always)]
229            fn bitxor(self, other: &SafeDec<D>) -> SafeDec<D> {
230                SafeDec(SafeDec::<D>::scale_up(&SafeInt::from(self)).bitxor(other.0.clone()))
231            }
232        }
233
234        impl<const D: usize> Mul<&SafeDec<D>> for $prim {
235            type Output = SafeDec<D>;
236
237            #[inline(always)]
238            fn mul(self, other: &SafeDec<D>) -> SafeDec<D> {
239                SafeDec(SafeInt::from(self).mul(other.0.clone()))
240            }
241        }
242    };
243}
244
245macro_rules! impl_decimal_div_for_primitive {
246    ($prim:ty, rhs_value) => {
247        impl<const D: usize> Div<SafeDec<D>> for $prim {
248            type Output = Option<SafeDec<D>>;
249
250            #[inline(always)]
251            fn div(self, other: SafeDec<D>) -> Option<SafeDec<D>> {
252                Some(SafeDec(
253                    SafeDec::<D>::scale_up(&SafeInt::from(self)).div(other.0)?,
254                ))
255            }
256        }
257    };
258    ($prim:ty, rhs_ref) => {
259        impl<const D: usize> Div<&SafeDec<D>> for $prim {
260            type Output = Option<SafeDec<D>>;
261
262            #[inline(always)]
263            fn div(self, other: &SafeDec<D>) -> Option<SafeDec<D>> {
264                Some(SafeDec(
265                    SafeDec::<D>::scale_up(&SafeInt::from(self)).div(other.0.clone())?,
266                ))
267            }
268        }
269    };
270}
271
272macro_rules! for_each_primitive {
273    ($macro:ident, $rhs_kind:ident) => {
274        $macro!(u8, $rhs_kind);
275        $macro!(u16, $rhs_kind);
276        $macro!(u32, $rhs_kind);
277        $macro!(u64, $rhs_kind);
278        $macro!(u128, $rhs_kind);
279        $macro!(i8, $rhs_kind);
280        $macro!(i16, $rhs_kind);
281        $macro!(i32, $rhs_kind);
282        $macro!(i64, $rhs_kind);
283        $macro!(i128, $rhs_kind);
284        $macro!(usize, $rhs_kind);
285        $macro!(isize, $rhs_kind);
286    };
287}
288
289macro_rules! impl_decimal_ops_for_safe_dec {
290    (lhs_value, rhs_value) => {
291        impl<const D: usize> Add<SafeDec<D>> for SafeDec<D> {
292            type Output = SafeDec<D>;
293
294            #[inline(always)]
295            fn add(self, other: SafeDec<D>) -> SafeDec<D> {
296                SafeDec(self.0.add(other.0))
297            }
298        }
299
300        impl<const D: usize> Sub<SafeDec<D>> for SafeDec<D> {
301            type Output = SafeDec<D>;
302
303            #[inline(always)]
304            fn sub(self, other: SafeDec<D>) -> SafeDec<D> {
305                SafeDec(self.0.sub(other.0))
306            }
307        }
308
309        impl<const D: usize> BitAnd<SafeDec<D>> for SafeDec<D> {
310            type Output = SafeDec<D>;
311
312            #[inline(always)]
313            fn bitand(self, other: SafeDec<D>) -> SafeDec<D> {
314                SafeDec(self.0.bitand(other.0))
315            }
316        }
317
318        impl<const D: usize> BitOr<SafeDec<D>> for SafeDec<D> {
319            type Output = SafeDec<D>;
320
321            #[inline(always)]
322            fn bitor(self, other: SafeDec<D>) -> SafeDec<D> {
323                SafeDec(self.0.bitor(other.0))
324            }
325        }
326
327        impl<const D: usize> BitXor<SafeDec<D>> for SafeDec<D> {
328            type Output = SafeDec<D>;
329
330            #[inline(always)]
331            fn bitxor(self, other: SafeDec<D>) -> SafeDec<D> {
332                SafeDec(self.0.bitxor(other.0))
333            }
334        }
335    };
336    (lhs_ref, rhs_value) => {
337        impl<const D: usize> Add<SafeDec<D>> for &SafeDec<D> {
338            type Output = SafeDec<D>;
339
340            #[inline(always)]
341            fn add(self, other: SafeDec<D>) -> SafeDec<D> {
342                SafeDec(self.clone().0.add(other.0))
343            }
344        }
345
346        impl<const D: usize> Sub<SafeDec<D>> for &SafeDec<D> {
347            type Output = SafeDec<D>;
348
349            #[inline(always)]
350            fn sub(self, other: SafeDec<D>) -> SafeDec<D> {
351                SafeDec(self.clone().0.sub(other.0))
352            }
353        }
354
355        impl<const D: usize> BitAnd<SafeDec<D>> for &SafeDec<D> {
356            type Output = SafeDec<D>;
357
358            #[inline(always)]
359            fn bitand(self, other: SafeDec<D>) -> SafeDec<D> {
360                SafeDec(self.clone().0.bitand(other.0))
361            }
362        }
363
364        impl<const D: usize> BitOr<SafeDec<D>> for &SafeDec<D> {
365            type Output = SafeDec<D>;
366
367            #[inline(always)]
368            fn bitor(self, other: SafeDec<D>) -> SafeDec<D> {
369                SafeDec(self.clone().0.bitor(other.0))
370            }
371        }
372
373        impl<const D: usize> BitXor<SafeDec<D>> for &SafeDec<D> {
374            type Output = SafeDec<D>;
375
376            #[inline(always)]
377            fn bitxor(self, other: SafeDec<D>) -> SafeDec<D> {
378                SafeDec(self.clone().0.bitxor(other.0))
379            }
380        }
381    };
382    (lhs_value, rhs_ref) => {
383        impl<const D: usize> Add<&SafeDec<D>> for SafeDec<D> {
384            type Output = SafeDec<D>;
385
386            #[inline(always)]
387            fn add(self, other: &SafeDec<D>) -> SafeDec<D> {
388                SafeDec(self.0.add(other.0.clone()))
389            }
390        }
391
392        impl<const D: usize> Sub<&SafeDec<D>> for SafeDec<D> {
393            type Output = SafeDec<D>;
394
395            #[inline(always)]
396            fn sub(self, other: &SafeDec<D>) -> SafeDec<D> {
397                SafeDec(self.0.sub(other.0.clone()))
398            }
399        }
400
401        impl<const D: usize> BitAnd<&SafeDec<D>> for SafeDec<D> {
402            type Output = SafeDec<D>;
403
404            #[inline(always)]
405            fn bitand(self, other: &SafeDec<D>) -> SafeDec<D> {
406                SafeDec(self.0.bitand(other.0.clone()))
407            }
408        }
409
410        impl<const D: usize> BitOr<&SafeDec<D>> for SafeDec<D> {
411            type Output = SafeDec<D>;
412
413            #[inline(always)]
414            fn bitor(self, other: &SafeDec<D>) -> SafeDec<D> {
415                SafeDec(self.0.bitor(other.0.clone()))
416            }
417        }
418
419        impl<const D: usize> BitXor<&SafeDec<D>> for SafeDec<D> {
420            type Output = SafeDec<D>;
421
422            #[inline(always)]
423            fn bitxor(self, other: &SafeDec<D>) -> SafeDec<D> {
424                SafeDec(self.0.bitxor(other.0.clone()))
425            }
426        }
427    };
428    (lhs_ref, rhs_ref) => {
429        impl<const D: usize> Add<&SafeDec<D>> for &SafeDec<D> {
430            type Output = SafeDec<D>;
431
432            #[inline(always)]
433            fn add(self, other: &SafeDec<D>) -> SafeDec<D> {
434                SafeDec(self.clone().0.add(other.0.clone()))
435            }
436        }
437
438        impl<const D: usize> Sub<&SafeDec<D>> for &SafeDec<D> {
439            type Output = SafeDec<D>;
440
441            #[inline(always)]
442            fn sub(self, other: &SafeDec<D>) -> SafeDec<D> {
443                SafeDec(self.clone().0.sub(other.0.clone()))
444            }
445        }
446
447        impl<const D: usize> BitAnd<&SafeDec<D>> for &SafeDec<D> {
448            type Output = SafeDec<D>;
449
450            #[inline(always)]
451            fn bitand(self, other: &SafeDec<D>) -> SafeDec<D> {
452                SafeDec(self.clone().0.bitand(other.0.clone()))
453            }
454        }
455
456        impl<const D: usize> BitOr<&SafeDec<D>> for &SafeDec<D> {
457            type Output = SafeDec<D>;
458
459            #[inline(always)]
460            fn bitor(self, other: &SafeDec<D>) -> SafeDec<D> {
461                SafeDec(self.clone().0.bitor(other.0.clone()))
462            }
463        }
464
465        impl<const D: usize> BitXor<&SafeDec<D>> for &SafeDec<D> {
466            type Output = SafeDec<D>;
467
468            #[inline(always)]
469            fn bitxor(self, other: &SafeDec<D>) -> SafeDec<D> {
470                SafeDec(self.clone().0.bitxor(other.0.clone()))
471            }
472        }
473    };
474}
475
476macro_rules! impl_decimal_ops_for_safe_int {
477    (lhs_value, rhs_value) => {
478        impl<const D: usize> Add<SafeDec<D>> for SafeInt {
479            type Output = SafeDec<D>;
480
481            #[inline(always)]
482            fn add(self, other: SafeDec<D>) -> SafeDec<D> {
483                SafeDec(SafeDec::<D>::scale_up(&self).add(other.0))
484            }
485        }
486
487        impl<const D: usize> Sub<SafeDec<D>> for SafeInt {
488            type Output = SafeDec<D>;
489
490            #[inline(always)]
491            fn sub(self, other: SafeDec<D>) -> SafeDec<D> {
492                SafeDec(SafeDec::<D>::scale_up(&self).sub(other.0))
493            }
494        }
495
496        impl<const D: usize> BitAnd<SafeDec<D>> for SafeInt {
497            type Output = SafeDec<D>;
498
499            #[inline(always)]
500            fn bitand(self, other: SafeDec<D>) -> SafeDec<D> {
501                SafeDec(SafeDec::<D>::scale_up(&self).bitand(other.0))
502            }
503        }
504
505        impl<const D: usize> BitOr<SafeDec<D>> for SafeInt {
506            type Output = SafeDec<D>;
507
508            #[inline(always)]
509            fn bitor(self, other: SafeDec<D>) -> SafeDec<D> {
510                SafeDec(SafeDec::<D>::scale_up(&self).bitor(other.0))
511            }
512        }
513
514        impl<const D: usize> BitXor<SafeDec<D>> for SafeInt {
515            type Output = SafeDec<D>;
516
517            #[inline(always)]
518            fn bitxor(self, other: SafeDec<D>) -> SafeDec<D> {
519                SafeDec(SafeDec::<D>::scale_up(&self).bitxor(other.0))
520            }
521        }
522
523        impl<const D: usize> Mul<SafeDec<D>> for SafeInt {
524            type Output = SafeDec<D>;
525
526            #[inline(always)]
527            fn mul(self, other: SafeDec<D>) -> SafeDec<D> {
528                SafeDec(self.mul(other.0))
529            }
530        }
531    };
532    (lhs_ref, rhs_value) => {
533        impl<const D: usize> Add<SafeDec<D>> for &SafeInt {
534            type Output = SafeDec<D>;
535
536            #[inline(always)]
537            fn add(self, other: SafeDec<D>) -> SafeDec<D> {
538                SafeDec(SafeDec::<D>::scale_up(self).add(other.0))
539            }
540        }
541
542        impl<const D: usize> Sub<SafeDec<D>> for &SafeInt {
543            type Output = SafeDec<D>;
544
545            #[inline(always)]
546            fn sub(self, other: SafeDec<D>) -> SafeDec<D> {
547                SafeDec(SafeDec::<D>::scale_up(self).sub(other.0))
548            }
549        }
550
551        impl<const D: usize> BitAnd<SafeDec<D>> for &SafeInt {
552            type Output = SafeDec<D>;
553
554            #[inline(always)]
555            fn bitand(self, other: SafeDec<D>) -> SafeDec<D> {
556                SafeDec(SafeDec::<D>::scale_up(self).bitand(other.0))
557            }
558        }
559
560        impl<const D: usize> BitOr<SafeDec<D>> for &SafeInt {
561            type Output = SafeDec<D>;
562
563            #[inline(always)]
564            fn bitor(self, other: SafeDec<D>) -> SafeDec<D> {
565                SafeDec(SafeDec::<D>::scale_up(self).bitor(other.0))
566            }
567        }
568
569        impl<const D: usize> BitXor<SafeDec<D>> for &SafeInt {
570            type Output = SafeDec<D>;
571
572            #[inline(always)]
573            fn bitxor(self, other: SafeDec<D>) -> SafeDec<D> {
574                SafeDec(SafeDec::<D>::scale_up(self).bitxor(other.0))
575            }
576        }
577
578        impl<const D: usize> Mul<SafeDec<D>> for &SafeInt {
579            type Output = SafeDec<D>;
580
581            #[inline(always)]
582            fn mul(self, other: SafeDec<D>) -> SafeDec<D> {
583                SafeDec(self.mul(other.0))
584            }
585        }
586    };
587    (lhs_value, rhs_ref) => {
588        impl<const D: usize> Add<&SafeDec<D>> for SafeInt {
589            type Output = SafeDec<D>;
590
591            #[inline(always)]
592            fn add(self, other: &SafeDec<D>) -> SafeDec<D> {
593                SafeDec(SafeDec::<D>::scale_up(&self).add(other.0.clone()))
594            }
595        }
596
597        impl<const D: usize> Sub<&SafeDec<D>> for SafeInt {
598            type Output = SafeDec<D>;
599
600            #[inline(always)]
601            fn sub(self, other: &SafeDec<D>) -> SafeDec<D> {
602                SafeDec(SafeDec::<D>::scale_up(&self).sub(other.0.clone()))
603            }
604        }
605
606        impl<const D: usize> BitAnd<&SafeDec<D>> for SafeInt {
607            type Output = SafeDec<D>;
608
609            #[inline(always)]
610            fn bitand(self, other: &SafeDec<D>) -> SafeDec<D> {
611                SafeDec(SafeDec::<D>::scale_up(&self).bitand(other.0.clone()))
612            }
613        }
614
615        impl<const D: usize> BitOr<&SafeDec<D>> for SafeInt {
616            type Output = SafeDec<D>;
617
618            #[inline(always)]
619            fn bitor(self, other: &SafeDec<D>) -> SafeDec<D> {
620                SafeDec(SafeDec::<D>::scale_up(&self).bitor(other.0.clone()))
621            }
622        }
623
624        impl<const D: usize> BitXor<&SafeDec<D>> for SafeInt {
625            type Output = SafeDec<D>;
626
627            #[inline(always)]
628            fn bitxor(self, other: &SafeDec<D>) -> SafeDec<D> {
629                SafeDec(SafeDec::<D>::scale_up(&self).bitxor(other.0.clone()))
630            }
631        }
632
633        impl<const D: usize> Mul<&SafeDec<D>> for SafeInt {
634            type Output = SafeDec<D>;
635
636            #[inline(always)]
637            fn mul(self, other: &SafeDec<D>) -> SafeDec<D> {
638                SafeDec(self.mul(other.0.clone()))
639            }
640        }
641    };
642    (lhs_ref, rhs_ref) => {
643        impl<const D: usize> Add<&SafeDec<D>> for &SafeInt {
644            type Output = SafeDec<D>;
645
646            #[inline(always)]
647            fn add(self, other: &SafeDec<D>) -> SafeDec<D> {
648                SafeDec(SafeDec::<D>::scale_up(self).add(other.0.clone()))
649            }
650        }
651
652        impl<const D: usize> Sub<&SafeDec<D>> for &SafeInt {
653            type Output = SafeDec<D>;
654
655            #[inline(always)]
656            fn sub(self, other: &SafeDec<D>) -> SafeDec<D> {
657                SafeDec(SafeDec::<D>::scale_up(self).sub(other.0.clone()))
658            }
659        }
660
661        impl<const D: usize> BitAnd<&SafeDec<D>> for &SafeInt {
662            type Output = SafeDec<D>;
663
664            #[inline(always)]
665            fn bitand(self, other: &SafeDec<D>) -> SafeDec<D> {
666                SafeDec(SafeDec::<D>::scale_up(self).bitand(other.0.clone()))
667            }
668        }
669
670        impl<const D: usize> BitOr<&SafeDec<D>> for &SafeInt {
671            type Output = SafeDec<D>;
672
673            #[inline(always)]
674            fn bitor(self, other: &SafeDec<D>) -> SafeDec<D> {
675                SafeDec(SafeDec::<D>::scale_up(self).bitor(other.0.clone()))
676            }
677        }
678
679        impl<const D: usize> BitXor<&SafeDec<D>> for &SafeInt {
680            type Output = SafeDec<D>;
681
682            #[inline(always)]
683            fn bitxor(self, other: &SafeDec<D>) -> SafeDec<D> {
684                SafeDec(SafeDec::<D>::scale_up(self).bitxor(other.0.clone()))
685            }
686        }
687
688        impl<const D: usize> Mul<&SafeDec<D>> for &SafeInt {
689            type Output = SafeDec<D>;
690
691            #[inline(always)]
692            fn mul(self, other: &SafeDec<D>) -> SafeDec<D> {
693                SafeDec(self.mul(other.0.clone()))
694            }
695        }
696    };
697}
698
699for_each_primitive!(impl_decimal_ops_for_primitive, rhs_value);
700for_each_primitive!(impl_decimal_ops_for_primitive, rhs_ref);
701for_each_primitive!(impl_decimal_div_for_primitive, rhs_value);
702for_each_primitive!(impl_decimal_div_for_primitive, rhs_ref);
703
704impl_decimal_ops_for_safe_dec!(lhs_value, rhs_value);
705impl_decimal_ops_for_safe_dec!(lhs_ref, rhs_value);
706impl_decimal_ops_for_safe_dec!(lhs_value, rhs_ref);
707impl_decimal_ops_for_safe_dec!(lhs_ref, rhs_ref);
708
709impl_decimal_ops_for_safe_int!(lhs_value, rhs_value);
710impl_decimal_ops_for_safe_int!(lhs_ref, rhs_value);
711impl_decimal_ops_for_safe_int!(lhs_value, rhs_ref);
712impl_decimal_ops_for_safe_int!(lhs_ref, rhs_ref);
713
714impl<const D: usize> Mul for SafeDec<D> {
715    type Output = SafeDec<D>;
716
717    fn mul(self, rhs: Self) -> Self::Output {
718        let raw_product = self.0 * rhs.0;
719        let scaled = SafeDec::<D>::scale_down(&raw_product);
720        SafeDec(scaled)
721    }
722}
723
724impl<const D: usize> Div<SafeDec<D>> for SafeDec<D> {
725    type Output = Option<SafeDec<D>>;
726
727    #[inline(always)]
728    fn div(self, other: SafeDec<D>) -> Option<SafeDec<D>> {
729        Some(SafeDec(
730            SafeDec::<D>::scale_up(&self.0).div(other.0.clone())?,
731        ))
732    }
733}
734
735impl<const D: usize> Div<&SafeDec<D>> for SafeDec<D> {
736    type Output = Option<SafeDec<D>>;
737
738    #[inline(always)]
739    fn div(self, other: &SafeDec<D>) -> Option<SafeDec<D>> {
740        Some(SafeDec(
741            SafeDec::<D>::scale_up(&self.0).div(other.0.clone())?,
742        ))
743    }
744}
745
746impl<const D: usize> Div<SafeDec<D>> for &SafeDec<D> {
747    type Output = Option<SafeDec<D>>;
748
749    #[inline(always)]
750    fn div(self, other: SafeDec<D>) -> Option<SafeDec<D>> {
751        Some(SafeDec(
752            SafeDec::<D>::scale_up(&self.0).div(other.0.clone())?,
753        ))
754    }
755}
756
757impl<const D: usize> Div<&SafeDec<D>> for &SafeDec<D> {
758    type Output = Option<SafeDec<D>>;
759
760    #[inline(always)]
761    fn div(self, other: &SafeDec<D>) -> Option<SafeDec<D>> {
762        Some(SafeDec(
763            SafeDec::<D>::scale_up(&self.0).div(other.0.clone())?,
764        ))
765    }
766}
767
768impl<const D: usize> Div<SafeInt> for SafeDec<D> {
769    type Output = Option<SafeDec<D>>;
770
771    #[inline(always)]
772    fn div(self, other: SafeInt) -> Option<SafeDec<D>> {
773        Some(SafeDec(self.0.div(other)?))
774    }
775}
776
777impl<const D: usize> Div<&SafeInt> for SafeDec<D> {
778    type Output = Option<SafeDec<D>>;
779
780    #[inline(always)]
781    fn div(self, other: &SafeInt) -> Option<SafeDec<D>> {
782        Some(SafeDec(self.0.div(other.clone())?))
783    }
784}
785
786impl<const D: usize> Div<SafeInt> for &SafeDec<D> {
787    type Output = Option<SafeDec<D>>;
788
789    #[inline(always)]
790    fn div(self, other: SafeInt) -> Option<SafeDec<D>> {
791        Some(SafeDec(self.0.clone().div(other)?))
792    }
793}
794
795impl<const D: usize> Div<&SafeInt> for &SafeDec<D> {
796    type Output = Option<SafeDec<D>>;
797
798    #[inline(always)]
799    fn div(self, other: &SafeInt) -> Option<SafeDec<D>> {
800        Some(SafeDec(self.0.clone().div(other.clone())?))
801    }
802}
803
804impl<const D: usize> Div<SafeDec<D>> for SafeInt {
805    type Output = Option<SafeDec<D>>;
806
807    #[inline(always)]
808    fn div(self, other: SafeDec<D>) -> Option<SafeDec<D>> {
809        Some(SafeDec(self.div(other.0)?))
810    }
811}
812
813impl<const D: usize> Div<&SafeDec<D>> for SafeInt {
814    type Output = Option<SafeDec<D>>;
815
816    #[inline(always)]
817    fn div(self, other: &SafeDec<D>) -> Option<SafeDec<D>> {
818        Some(SafeDec(self.div(other.0.clone())?))
819    }
820}
821
822impl<const D: usize> Div<SafeDec<D>> for &SafeInt {
823    type Output = Option<SafeDec<D>>;
824
825    #[inline(always)]
826    fn div(self, other: SafeDec<D>) -> Option<SafeDec<D>> {
827        Some(SafeDec(self.clone().div(other.0)?))
828    }
829}
830
831impl<const D: usize> Div<&SafeDec<D>> for &SafeInt {
832    type Output = Option<SafeDec<D>>;
833
834    #[inline(always)]
835    fn div(self, other: &SafeDec<D>) -> Option<SafeDec<D>> {
836        Some(SafeDec(self.clone().div(other.0.clone())?))
837    }
838}
839
840impl<const D: usize, O> AddAssign<O> for SafeDec<D>
841where
842    SafeDec<D>: Add<O, Output = SafeDec<D>>,
843{
844    #[inline(always)]
845    fn add_assign(&mut self, rhs: O) {
846        *self = self.clone() + rhs;
847    }
848}
849
850impl<const D: usize, O> MulAssign<O> for SafeDec<D>
851where
852    SafeDec<D>: Mul<O, Output = SafeDec<D>>,
853{
854    #[inline(always)]
855    fn mul_assign(&mut self, rhs: O) {
856        *self = self.clone() * rhs;
857    }
858}
859
860impl<const D: usize, O> SubAssign<O> for SafeDec<D>
861where
862    SafeDec<D>: Sub<O, Output = SafeDec<D>>,
863{
864    #[inline(always)]
865    fn sub_assign(&mut self, rhs: O) {
866        *self = self.clone() - rhs;
867    }
868}
869
870#[test]
871fn test_safe_dec_from_str() {
872    let parsed = "123.456".parse::<SafeDec<3>>().unwrap();
873    assert_eq!(parsed.0, SafeInt::from(123456));
874    let parsed = "123.456".parse::<SafeDec<4>>().unwrap();
875    assert_eq!(parsed.0, SafeInt::from(1234560));
876}
877
878#[test]
879fn test_safe_dec_add() {
880    let a = "123.456".parse::<SafeDec<3>>().unwrap();
881    let b = "654.321".parse::<SafeDec<3>>().unwrap();
882    let c = a.clone() + b;
883    assert_eq!(c.0, SafeInt::from(123456 + 654321));
884    assert_eq!(c.to_string().as_str(), "777.777");
885    assert_eq!(c, SafeDec::from_raw(777777));
886    let mut d = c;
887    d += a;
888    assert_eq!(d.to_string().as_str(), "901.233");
889}
890
891#[test]
892fn test_safe_dec_sub() {
893    let a = "123.456".parse::<SafeDec<3>>().unwrap();
894    let b = "654.321".parse::<SafeDec<3>>().unwrap();
895    let c = a.clone() - b;
896    assert_eq!(c.0, SafeInt::from(123456 - 654321));
897    assert_eq!(c.to_string().as_str(), "-530.865");
898    assert_eq!(c, SafeDec::from_raw(-530865));
899    let mut d = c;
900    d -= a;
901    assert_eq!(d.to_string().as_str(), "-654.321");
902}
903
904#[test]
905fn test_safe_dec_mul() {
906    let a = "123.456".parse::<SafeDec<3>>().unwrap();
907    let b = "654.321".parse::<SafeDec<3>>().unwrap();
908    let c = a.clone() * b;
909    assert_eq!(c.to_string().as_str(), "80779.853");
910    let mut d = c;
911    d *= a;
912    assert_eq!(d.to_string().as_str(), "9972757.531");
913    let a = 4u64;
914    let b = "-247.842".parse::<SafeDec<3>>().unwrap();
915    let c = a * b;
916    assert_eq!(c.to_string().as_str(), "-991.368");
917}
918
919#[test]
920fn test_safe_dec_div() {
921    let a = "123.456".parse::<SafeDec<3>>().unwrap();
922    let b = "654.321".parse::<SafeDec<3>>().unwrap();
923    let c = b / a;
924    assert_eq!(c.unwrap().to_string().as_str(), "5.300");
925}
926
927#[test]
928fn test_safe_dec_safe_int_div() {
929    let a = "123.456".parse::<SafeDec<3>>().unwrap();
930    let b = SafeInt::from(654321);
931    let c = b / a;
932    assert_eq!(c, Some(SafeDec::from_raw(654321 / 123456)));
933}
934
935#[test]
936fn test_from_other_scale() {
937    let a = "123.455".parse::<SafeDec<3>>().unwrap();
938    let b = SafeDec::<4>::from_other_scale(a);
939    assert_eq!(b.to_string().as_str(), "123.4550");
940    let a = "123.4550".parse::<SafeDec<4>>().unwrap();
941    let b = SafeDec::<3>::from_other_scale(a);
942    assert_eq!(b.to_string().as_str(), "123.455");
943    let a = "123.456789".parse::<SafeDec<6>>().unwrap();
944    let b = SafeDec::<3>::from_other_scale(a);
945    assert_eq!(b.to_string().as_str(), "123.457");
946    let a = "123.456789".parse::<SafeDec<6>>().unwrap();
947    let b = SafeDec::<10>::from_other_scale(a);
948    assert_eq!(b.to_string().as_str(), "123.4567890000");
949}
950
951#[test]
952fn test_parsing_round_trip() {
953    assert_eq!(
954        "-0.000005587".parse::<SafeDec<10>>().unwrap().to_string(),
955        "-0.0000055870"
956    );
957}
958
959#[test]
960fn test_complex() {
961    let a = "-348973984.9879837849".parse::<SafeDec<10>>().unwrap();
962    let b = "195.0000000001".parse::<SafeDec<10>>().unwrap();
963    let c = b / a;
964    assert_eq!(c.unwrap(), "-0.0000005587".parse::<SafeDec<10>>().unwrap());
965    let a = "50.01".parse::<SafeDec<7>>().unwrap();
966    assert_eq!(a.to_string(), "50.0100000");
967    let b = "-2.9".parse::<SafeDec<7>>().unwrap();
968    assert_eq!(b.to_string(), "-2.9000000");
969    let c = a * b;
970    assert_eq!(c.to_string(), "-145.0290000");
971    let a = "33497398473894.1".parse::<SafeDec<10>>().unwrap();
972    let b = "0.0000000001".parse::<SafeDec<10>>().unwrap();
973    let c = a * b;
974    assert_eq!(c.to_string(), "3349.7398473894");
975    let a = "0.00005".parse::<SafeDec<5>>().unwrap();
976    let b = "0.00001".parse::<SafeDec<5>>().unwrap();
977    let c = a * b;
978    assert_eq!(c.to_string(), "0.00000"); // because truncation
979    let a = "0.00005".parse::<SafeDec<10>>().unwrap();
980    let b = "0.00001".parse::<SafeDec<10>>().unwrap();
981    let c = a * b;
982    assert_eq!(c.to_string(), "0.0000000005");
983    let a = SafeInt::from(5);
984    let b = "0.00001".parse::<SafeDec<10>>().unwrap();
985    let c = a * b;
986    assert_eq!(c.to_string(), "0.0000500000");
987}