fastnum2 0.3.2

fork of Fast decimal numbers library
Documentation
use core::num::IntErrorKind;

use crate::int::{intrinsics::*, UInt};

type U<const N: usize> = UInt<N>;

macro_rules! to_int_impl {
    ($to_int: ident, $int: ident) => {
        #[inline]
        pub const fn $to_int<const N: usize>(int: U<N>) -> Result<$int, IntErrorKind> {
            let digits = int.digits();
            let mut out = 0;
            let mut i = 0;

            if Digit::BITS > <$int>::BITS {
                let small = digits[i] as $int;
                let trunc = small as Digit;
                if digits[i] != trunc {
                    return Err(IntErrorKind::PosOverflow);
                }
                out = small;
                i = 1;
            } else {
                loop {
                    let shift = i << BIT_SHIFT;
                    if i >= N || shift >= <$int>::BITS as usize {
                        break;
                    }
                    out |= (digits[i] as $int) << shift;
                    i += 1;
                }
            }

            #[allow(unused_comparisons)]
            if out < 0 {
                return Err(IntErrorKind::PosOverflow);
            }

            while i < N {
                if digits[i] != 0 {
                    return Err(IntErrorKind::PosOverflow);
                }
                i += 1;
            }

            Ok(out)
        }
    };
}

macro_rules! from_uint_impl {
    ($from_uint: ident, $uint: ident) => {
        #[inline]
        pub const fn $from_uint<const N: usize>(uint: $uint) -> U<N> {
            const UINT_BITS: usize = $uint::BITS as usize;
            debug_assert!(UINT_BITS <= N * (BITS as usize));

            let mut digits = [0; N];
            let mut i = 0;
            while i << BIT_SHIFT < UINT_BITS {
                let d = (uint >> (i << BIT_SHIFT)) as Digit;
                if d != 0 {
                    digits[i] = d;
                }
                i += 1;
            }
            U::from_digits(digits)
        }
    };
}

to_int_impl!(to_u8, u8);
to_int_impl!(to_u16, u16);
to_int_impl!(to_u32, u32);
to_int_impl!(to_u64, u64);
to_int_impl!(to_u128, u128);
to_int_impl!(to_usize, usize);

to_int_impl!(to_i8, i8);
to_int_impl!(to_i16, i16);
to_int_impl!(to_i32, i32);
to_int_impl!(to_i64, i64);
to_int_impl!(to_i128, i128);
to_int_impl!(to_isize, isize);

from_uint_impl!(from_u8, u8);
from_uint_impl!(from_u16, u16);
from_uint_impl!(from_u32, u32);
from_uint_impl!(from_u64, u64);
from_uint_impl!(from_u128, u128);
from_uint_impl!(from_usize, usize);