1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
use core::fmt::{Display, Debug};

use crate::{BigUInt, digit::Digit};
use crate::property::IsBigInt;

impl<T: Digit, const LEN: usize> Display for BigUInt<T, LEN> 
where
    [(); Self::BYTE_LEN * 2]:
{
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        let mut out = [0_u8; Self::BYTE_LEN * 2];
        hex::encode_to_slice(self.as_bytes(), &mut out).unwrap();
        out.chunks(2).rev().flatten().try_for_each(|v| Display::fmt(&(*v as char), f))
    }
}

impl<T: Digit, const LEN: usize> Debug for BigUInt<T, LEN> 
where
    [(); Self::BYTE_LEN * 2]:
{
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        let mut out = [0_u8; Self::BYTE_LEN * 2];
        hex::encode_to_slice(self.as_bytes(), &mut out).unwrap();
        out.chunks(2).rev().flatten().try_for_each(|v| Display::fmt(&(*v as char), f))
    }
}

impl<T: Digit, const LEN: usize> BigUInt<T, LEN> 
where
    Self: IsBigInt,
    [(); LEN * T::BYTE_LEN]: 
{
    pub const fn from_bytes(mut value: &[u8]) -> Self {
        while !value.is_empty() && value[0] == 0 {
            value = value.split_at(1).1;
        }
        if Self::BYTE_LEN < value.len() {
            panic!("trying to convert string to biguint with overflow")
        }
        let mut buf = [0; LEN * T::BYTE_LEN];
        let mut i = 0;
        loop {
            if i >= value.len() { break; }
            buf[i] = value[value.len() - i - 1];
            i += 1;
        }
        
        unsafe { core::mem::transmute_copy(&buf) }
    }
}

#[macro_export]
macro_rules! bigint {
    ($t:ty, $s:expr) => {
        <$t>::from_bytes($crate::hex_literal::hex!($s).as_slice())
    };
}