use rand::Rng;
use super::*;
#[test]
fn test_len() {
let mut z = [0u8; 16];
from_int(15, &mut z, 254);
assert_eq!(len(15, &z), 1);
let mut z2 = [0u8; 16];
from_int(15, &mut z2, 256);
assert_eq!(len(15, &z2), 2);
}
fn coerce<T, U>(f: impl FnMut(T, T) -> U) -> impl FnMut(T, T) -> U {
f
}
macro_rules! with {
(fn $ident:ident = $f:expr => $f2:expr) => {
#[test]
fn $ident() {
let mut r = rand::rng();
for n in 0..500 {
let mut b = [0; 64];
let mut a = [0; 64];
let a_ = r.next_u64() as _;
let b_ = r.next_u64() as _;
let Some(ought) =
coerce::<u128, Option<u128>>($f2)(a_, b_)
else {
continue;
};
// dbg!(a_, b_);
from_int(63, &mut a, a_);
from_int(63, &mut b, b_);
let mut o = coerce::<[u8; 64], u128>($f)(a, b);
// let x = to_int(63, &o);s
assert_eq!(o, ought);
}
}
};
}
with! {fn roundtrip = |a, b| {
to_int(63, &a)
} => |a, b| Some(a) }
with!(fn test_add = |a, b| {
let mut o = [0;64];
add(63, &mut o, &a, &b, false);
to_int(63, &o)
} => |a, b| a.checked_add(b));
with!(fn test_sub = |a, b| {
let mut o = [0;64];
sub(63, &mut o, &a, &b, false);
to_int(63, &o)
} => |a: u128, b:u128| a.checked_sub(b));
with!(fn test_mul = |a, b| {
let mut o = [0;126];
mul(&mut o,63, &a,63,&b);
to_int(126, &o)
} => |a: u128, b:u128| a.checked_mul(b));
with!(fn test_div = |a, b|{
let mut q = [0;63];
let mut r = [0;63];
let mut tmp = [0;63+63+2];
div(63, &mut q, &a, 63,&b,&mut r,&mut tmp);
to_int(63, &q)
}=>|a, b| a.checked_div(b));
with!(fn test_shl = |a, b| {
let mut o = [0;63];
shl(63,&mut o, 63, &a,to_int(63, &b) as u8 as _, 0);
to_int(63, &o)
}=>|a, b| a.checked_shl(b as u8 as _));
with!(fn test_shr = |a, b| {
let mut o = [0;63];
shr(63,&mut o, 63, &a,to_int(63, &b) as u8 as _, 0);
to_int(63, &o)
}=>|a, b| a.checked_shr(b as u8 as _));
with!(fn test_cmp = |a, b| cmp(63, &a, &b) as u128
=>|a, b| Some((a.cmp(&b)) as u128));
#[test]
fn test_tos() {
for n in 0..50000 {
let mut z = [0; 64];
from_int(63, &mut z, n);
let z = z;
let x = to_int(63, &z);
let mut str = vec![];
let str = to_str(&mut str, 10, 63, &mut { z });
assert_eq!(std::str::from_utf8(str), Ok(&*n.to_string()));
assert_eq!(x, n);
for b in 2..32 {
let mut y = vec![];
let mut a = [0; 64];
let str = to_str(&mut y, b, 63, &mut z.clone());
assert_eq!(from_str(63, &mut a, b, str), 0);
let mut t1 = [0; 33];
let mut t2 = [0; 33];
assert_eq!(
u64::from_str_radix(
std::str::from_utf8(str).unwrap(),
b as _
)
.unwrap() as u128,
n
);
}
}
}