fastnum/decimal/dec/impls/
cast.rs1use crate::{
2 bint,
3 bint::UInt,
4 decimal::{Decimal, ParseError, Sign, UnsignedDecimal},
5 utils::const_generics::{Dimension, Narrow, Widen},
6 Cast, TryCast,
7};
8
9type D<const N: usize> = Decimal<N>;
10type UD<const N: usize> = UnsignedDecimal<N>;
11
12impl<const N: usize, const M: usize> Cast<D<N>> for D<M>
13where
14 Dimension<N, M>: Widen,
15{
16 #[inline(always)]
17 fn cast(self) -> D<N> {
18 D::new(self.digits.cast(), self.cb)
19 }
20}
21
22impl<const N: usize, const M: usize> TryCast<D<N>> for D<M>
23where
24 Dimension<N, M>: Narrow,
25{
26 type Error = ParseError;
27
28 #[inline(always)]
29 fn try_cast(self) -> Result<D<N>, Self::Error> {
30 <UInt<M> as TryCast<UInt<N>>>::try_cast(self.digits)
31 .map(|digits| D::new(digits, self.cb))
32 .map_err(|e| map_error(e, self.sign()))
33 }
34}
35
36impl<const N: usize, const M: usize> TryCast<UD<N>> for D<M> {
37 type Error = ParseError;
38
39 #[inline(always)]
40 fn try_cast(self) -> Result<UD<N>, Self::Error> {
41 if self.is_negative() {
42 Err(ParseError::Signed)
43 } else {
44 debug_assert!(self.is_positive());
45
46 if N >= M || self.digits().bits() <= UInt::<N>::BITS {
47 #[allow(unsafe_code)]
51 {
52 let d = unsafe { self._transmute() };
53 Ok(UD::new(d))
54 }
55 } else {
56 Err(map_overflow(self.sign()))
57 }
58 }
59 }
60}
61
62#[inline(always)]
63fn map_overflow(sign: Sign) -> ParseError {
64 match sign {
65 Sign::Plus => ParseError::PosOverflow,
66 Sign::Minus => ParseError::NegOverflow,
67 }
68}
69
70#[inline(always)]
71fn map_error(e: bint::ParseError, sign: Sign) -> ParseError {
72 match e {
73 bint::ParseError::Empty => ParseError::Empty,
74 bint::ParseError::InvalidDigit => ParseError::InvalidLiteral,
75 bint::ParseError::PosOverflow => map_overflow(sign),
76 bint::ParseError::NegOverflow => ParseError::NegOverflow,
77 bint::ParseError::Zero => ParseError::Unknown,
78 bint::ParseError::Signed => ParseError::Signed,
79 bint::ParseError::InvalidRadix => ParseError::InvalidRadix,
80 bint::ParseError::Unknown => ParseError::Unknown,
81 }
82}