kago 0.3.0

A crate for custom-width signed and unsigned integers.
Documentation
use crate::*;
use num_traits::*;
use pretty_assertions::assert_eq;
use rstest::*;

#[fixture]
fn u10_vec() -> Vec<u16> {
    (0..(1u16 << 10)).collect::<Vec<u16>>()
}

#[rstest]
fn test_u10_add(u10_vec: Vec<u16>) {
    for i in u10_vec.iter() {
        for j in u10_vec.iter() {
            let i = *i;
            let j = *j;
            let x = U10::new(i);
            let y = U10::new(j);
            if i + j < 1024 {
                let expected = U10::new(i + j);
                assert_eq!(x + y, expected);
                assert_eq!(x.checked_add(&y), Some(expected));
            } else {
                assert_eq!(x.checked_add(&y), None);
            }

            // wrapping版のテスト
            let expected = i.wrapping_add(j);
            let expected = if expected >= 1024 {
                // wrapping_addは1024以上の値を返す
                expected & 1023
            } else {
                expected
            };
            let expected = U10::new(expected);
            assert_eq!(x.wrapping_add(&y), expected);
        }
    }
}

#[rstest]
fn test_u10_sub(u10_vec: Vec<u16>) {
    for i in u10_vec.iter() {
        for j in u10_vec.iter() {
            let i = *i;
            let j = *j;
            let x = U10::new(i);
            let y = U10::new(j);
            if i >= j {
                let expected = U10::new(i - j);
                assert_eq!(x - y, expected);
                assert_eq!(x.checked_sub(&y), Some(expected));
            } else {
                assert_eq!(x.checked_sub(&y), None);
            }

            // wrapping版のテスト
            let expected = i.wrapping_sub(j);
            let expected = if expected >= 1024 {
                // wrapping_subは1024以上の値を返す
                expected & 1023
            } else {
                expected
            };
            let expected = U10::new(expected);
            assert_eq!(x.wrapping_sub(&y), expected);
        }
    }
}

#[rstest]
fn test_u10_mul(u10_vec: Vec<u16>) {
    for i in u10_vec.iter() {
        for j in u10_vec.iter() {
            let i = *i;
            let j = *j;
            let x = U10::new(i);
            let y = U10::new(j);
            if i == 0 || j == 0 {
                assert_eq!(x * y, U10::new(0));
                assert_eq!(x.checked_mul(&y), Some(U10::new(0)));
            } else if 1024 / i >= j && i * j < 1024 {
                let expected = U10::new(i * j);
                assert_eq!(x * y, expected);
                assert_eq!(x.checked_mul(&y), Some(expected));
            } else {
                assert_eq!(x.checked_mul(&y), None);
            }
        }
    }
}

#[rstest]
fn test_u10_div(u10_vec: Vec<u16>) {
    for i in u10_vec.iter() {
        for j in u10_vec.iter() {
            let i = *i;
            let j = *j;
            let x = U10::new(i);
            let y = U10::new(j);
            if j != 0 {
                let expected = U10::new(i / j);
                assert_eq!(x / y, expected);
                assert_eq!(x.checked_div(&y), Some(expected));
            } else {
                assert_eq!(x.checked_div(&y), None);
            }
        }
    }
}

#[rstest]
fn test_u10_rem(u10_vec: Vec<u16>) {
    for i in u10_vec.iter() {
        for j in u10_vec.iter() {
            let i = *i;
            let j = *j;
            let x = U10::new(i);
            let y = U10::new(j);
            if j != 0 {
                let expected = U10::new(i % j);
                assert_eq!(x % y, expected);
                assert_eq!(x.checked_rem(&y), Some(expected));
            } else {
                assert_eq!(x.checked_rem(&y), None);
            }
        }
    }
}