smallint 0.2.2

A library for optimized arbitrary precision integers.
Documentation
#![cfg(feature = "num-bigint")]

use num_bigint::BigInt;
use num_bigint::BigUint;
use num_bigint::Sign;

use core::mem::ManuallyDrop;

use crate::SmallInt;
use crate::SmallUint;

use crate::smallint::SmallIntType;
use crate::smallint::SmallUintType;

impl From<&BigInt> for SmallInt {
    fn from(b: &BigInt) -> Self {
        match b.try_into() {
            Ok(i) => Self(SmallIntType::Inline(i)),
            Err(_) => {
                let (sign, vec) = b.to_u32_digits();
                let mut slice = ManuallyDrop::new(vec.into_boxed_slice());
                let size = match sign {
                    Sign::Minus => -isize::try_from(slice.len()).unwrap(),
                    Sign::NoSign => panic!(
                        "Shouldn't happen; BigInts which store zero should convert to inline."
                    ),
                    Sign::Plus => isize::try_from(slice.len()).unwrap(),
                };
                Self(SmallIntType::Heap((slice.as_mut_ptr(), size)))
            }
        }
    }
}

impl From<&SmallInt> for BigInt {
    fn from(s: &SmallInt) -> Self {
        match s.0 {
            SmallIntType::Inline(i) => Self::from(i),
            SmallIntType::Heap((r, s)) => {
                let size = usize::try_from(s.abs()).unwrap();
                let sign = s.signum();
                let slice = unsafe { core::slice::from_raw_parts(r, size) };
                let bs = match sign {
                    0 => Sign::NoSign,
                    -1 => Sign::Minus,
                    1 => Sign::Plus,
                    _ => panic!("This shouldn't happen; There are only 3 signums."),
                };

                BigInt::new(bs, slice.to_vec())
            }
        }
    }
}

impl From<&BigUint> for SmallUint {
    fn from(b: &BigUint) -> Self {
        match b.try_into() {
            Ok(i) => Self(SmallUintType::Inline(i)),
            Err(_) => {
                let vec = b.to_u32_digits();
                let mut slice = ManuallyDrop::new(vec.into_boxed_slice());
                let size = slice.len();
                Self(SmallUintType::Heap((slice.as_mut_ptr(), size)))
            }
        }
    }
}

impl From<&SmallUint> for BigUint {
    fn from(s: &SmallUint) -> Self {
        match s.0 {
            SmallUintType::Inline(i) => Self::from(i),
            SmallUintType::Heap((r, s)) => {
                let slice = unsafe { core::slice::from_raw_parts(r, s) };

                BigUint::new(slice.to_vec())
            }
        }
    }
}