kago 0.4.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 i10_vec() -> Vec<i16> {
    let min = -(1 << 9);
    let max = (1 << 9) - 1;
    (min..=max).collect::<Vec<i16>>()
}

#[rstest]
fn test_i10_add(i10_vec: Vec<i16>) {
    for i in i10_vec.iter() {
        for j in i10_vec.iter() {
            let i = *i;
            let j = *j;
            let x = I10::new(i);
            let y = I10::new(j);
            if (-512..512).contains(&(i + j)) {
                let expected = I10::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 >= 512 {
                expected.wrapping_sub(1024)
            } else if expected < -512 {
                expected.wrapping_add(1024)
            } else {
                expected
            };
            let expected = I10::new(expected);
            assert_eq!(x.wrapping_add(&y), expected);
        }
    }
}

#[rstest]
fn test_i10_sub(i10_vec: Vec<i16>) {
    for i in i10_vec.iter() {
        for j in i10_vec.iter() {
            let i = *i;
            let j = *j;
            let x = I10::new(i);
            let y = I10::new(j);
            if (-512..512).contains(&(i - j)) {
                let expected = I10::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 >= 512 {
                expected.wrapping_sub(1024)
            } else if expected < -512 {
                expected.wrapping_add(1024)
            } else {
                expected
            };
            let expected = I10::new(expected);
            assert_eq!(x.wrapping_sub(&y), expected);
        }
    }
}

#[rstest]
fn test_i10_mul(i10_vec: Vec<i16>) {
    for i in i10_vec.iter() {
        for j in i10_vec.iter() {
            let i = *i;
            let j = *j;
            let x = I10::new(i);
            let y = I10::new(j);
            if i == 0 || j == 0 {
                assert_eq!(x * y, I10::new(0));
                assert_eq!(x.checked_mul(&y), Some(I10::new(0)));
            } else if 512 / abs(i) >= abs(j) && (-512..512).contains(&(i * j)) {
                let expected = I10::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_i10_div(i10_vec: Vec<i16>) {
    for i in i10_vec.iter() {
        for j in i10_vec.iter() {
            let i = *i;
            let j = *j;
            let x = I10::new(i);
            let y = I10::new(j);
            if j != 0 && (-512..512).contains(&(i / j)) {
                let expected = I10::new(i / j);
                assert_eq!(x / y, expected);
                assert_eq!(x.checked_div(&y), Some(expected));
            } else {
                assert_eq!(
                    x.checked_div(&y),
                    None,
                    "{:?} / {:?} = {:?}",
                    x,
                    y,
                    i.checked_div(j)
                );
            }
        }
    }
}

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