safe_bigmath/
decimal.rs

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