fastnum2 0.3.6

fork of Fast decimal numbers library
Documentation
macro_rules! test_impl {
    (D, $bits: literal) => {
        paste::paste! { test_impl!(SIGNED: $bits, [< dec $bits >], [<D $bits>]); }
    };
    (UD, $bits: literal) => {
        paste::paste! { test_impl!(UNSIGNED: $bits, [< udec $bits >], [<UD $bits>]); }
    };
    (UNSIGNED: $bits: tt, $dec: ident, $D: ident) => {
        paste::paste! {
            mod [< $dec _unsigned >] {
                use rstest::*;
                use fastnum::{$dec, $D};
                use num_traits::{FromPrimitive, ToPrimitive};

                super::test_impl!(UNSIGNED:: $bits, $dec, $D);
            }
        }
    };
    (SIGNED: $bits: tt, $dec: ident, $D: ident) => {
        paste::paste! {
            mod [< $dec _signed >]{
                use rstest::*;
                use fastnum::{$dec, $D};
                use num_traits::{FromPrimitive, ToPrimitive};

                super::test_impl!(SIGNED:: $bits, $dec, $D);
            }
        }
    };
    (UNSIGNED:: 512, $dec: ident, $D: ident) => {
        super::test_impl!(UNSIGNED:: 256, $dec, $D);
    };
    (SIGNED:: 512, $dec: ident, $D: ident) => {
        super::test_impl!(SIGNED:: 256, $dec, $D);
    };
    (UNSIGNED:: 256, $dec: ident, $D: ident) => {
        super::test_impl!(UNSIGNED:: 128, $dec, $D);
    };
    (SIGNED:: 256, $dec: ident, $D: ident) => {
        super::test_impl!(SIGNED:: 128, $dec, $D);
    };
    (UNSIGNED:: 128, $dec: ident, $D: ident) => {
        super::test_impl!(UNSIGNED TO_UINT $dec, $D, u8, u16, u32, u64, u128, usize);
        super::test_impl!(UNSIGNED TO_INT $dec, $D, i8, i16, i32, i64, i128, isize);

        super::test_impl!(UNSIGNED FROM_UINT $dec, $D, u8, u16, u32, u64, u128, usize);
        super::test_impl!(UNSIGNED FROM_INT $dec, $D, i8, i16, i32, i64, i128, isize);
    };
    (SIGNED:: 128, $dec: ident, $D: ident) => {
        super::test_impl!(SIGNED TO_UINT $dec, $D, u8, u16, u32, u64, u128, usize);
        super::test_impl!(SIGNED TO_INT $dec, $D, i8, i16, i32, i64, i128, isize);

        super::test_impl!(SIGNED FROM_UINT $dec, $D, u8, u16, u32, u64, u128, usize);
        super::test_impl!(SIGNED FROM_INT $dec, $D, i8, i16, i32, i64, i128, isize);
    };
    (UNSIGNED TO_UINT $dec: ident, $D: ident, $($Pt: ty),*) => {
        $(
            paste::paste! {
                #[rstest(::trace)]
                #[case($dec!(0), 0)]
                #[case($dec!(1), 1)]
                #[case($dec!(10), 10)]
                #[case($dec!(10.5), 11)]
                #[case($D::from($Pt::MAX), $Pt::MAX)]
                #[case($D::from($Pt::MAX) - $dec!(1), $Pt::MAX - 1)]
                #[case($D::from($Pt::MAX) + $dec!(0.1), $Pt::MAX)]
                #[case($D::from($Pt::MAX) - $dec!(0.1), $Pt::MAX)]
                fn [< test_to_ $Pt >](#[case] d: $D, #[case] expected: $Pt) {
                    assert_eq!(<$D as ToPrimitive>::[< to_ $Pt>](&d), Some(expected));
                }
            }
        )*
    };
    (UNSIGNED TO_INT $dec: ident, $D: ident, $($Pt: ty),*) => {
        $(
            paste::paste! {
                #[rstest(::trace)]
                #[case($dec!(0), 0)]
                #[case($dec!(1), 1)]
                #[case($dec!(10), 10)]
                #[case($dec!(10.5), 11)]
                #[case($D::try_from($Pt::MAX).unwrap(), $Pt::MAX)]
                #[case($D::try_from($Pt::MAX).unwrap() - $dec!(1), $Pt::MAX - 1)]
                #[case($D::try_from($Pt::MAX).unwrap() + $dec!(0.1), $Pt::MAX)]
                #[case($D::try_from($Pt::MAX).unwrap() - $dec!(0.1), $Pt::MAX)]
                fn [< test_to_ $Pt >](#[case] d: $D, #[case] expected: $Pt) {
                    assert_eq!(<$D as ToPrimitive>::[< to_ $Pt>](&d), Some(expected));
                }
            }
        )*
    };
    (SIGNED TO_UINT $dec: ident, $D: ident, $($Pt: ty),*) => {
        $(
            paste::paste! {
                #[rstest(::trace)]
                #[case($dec!(0), 0)]
                #[case($dec!(1), 1)]
                #[case($dec!(10), 10)]
                #[case($dec!(10.5), 11)]
                #[case($D::from($Pt::MAX), $Pt::MAX)]
                #[case($D::from($Pt::MAX) - $dec!(1), $Pt::MAX - 1)]
                #[case($D::from($Pt::MAX) + $dec!(0.1), $Pt::MAX)]
                #[case($D::from($Pt::MAX) - $dec!(0.1), $Pt::MAX)]
                #[case($D::from($Pt::MAX) - $dec!(1), $Pt::MAX - 1)]
                fn [< test_to_ $Pt _signed>](#[case] d: $D, #[case] expected: $Pt) {
                    assert_eq!(<$D as ToPrimitive>::[< to_ $Pt>](&d), Some(expected));
                }

                #[rstest(::trace)]
                #[case($dec!(-0))]
                #[case($dec!(-1))]
                #[case($dec!(-10))]
                fn [< test_to_ $Pt _signed_negative>](#[case] d: $D) {
                    assert!(<$D as ToPrimitive>::[< to_ $Pt>](&d).is_none());
                }
            }
        )*
    };
    (SIGNED TO_INT $dec: ident, $D: ident, $($Pt: ty),*) => {
        $(
            paste::paste! {
                #[rstest(::trace)]
                #[case($dec!(0), 0)]
                #[case($dec!(1), 1)]
                #[case($dec!(10), 10)]
                #[case($dec!(10.1), 10)]
                #[case($dec!(10.5), 11)]
                #[case($dec!(-1), -1)]
                #[case($dec!(-0), 0)]
                #[case($dec!(-10.5), -11)]
                #[case($D::from($Pt::MAX), $Pt::MAX)]
                #[case($D::from($Pt::MAX) + $dec!(0.1), $Pt::MAX)]
                #[case($D::from($Pt::MAX) - $dec!(0.1), $Pt::MAX)]
                #[case($D::from($Pt::MAX) - $dec!(1), $Pt::MAX - 1)]
                #[case($D::from($Pt::MIN), $Pt::MIN)]
                #[case($D::from($Pt::MIN) + $dec!(1), $Pt::MIN + 1)]
                #[case($D::from($Pt::MIN) - $dec!(0.1), $Pt::MIN)]
                #[case($D::from($Pt::MAX).neg(), $Pt::MIN + 1)]
                fn [< test_to_ $Pt _signed>](#[case] d: $D, #[case] expected: $Pt) {
                    assert_eq!(<$D as ToPrimitive>::[< to_ $Pt>](&d), Some(expected));
                }

                #[rstest(::trace)]
                #[case($D::from($Pt::MIN).neg())]
                #[case($D::from($Pt::MAX) + $dec!(1))]
                #[case($D::from($Pt::MAX) + $dec!(0.5))]
                #[case($D::from($Pt::MIN) - $dec!(1))]
                #[case($D::from($Pt::MIN) - $dec!(0.5))]
                fn [< test_to_ $Pt _signed_negative>](#[case] d: $D) {
                    assert!(<$D as ToPrimitive>::[< to_ $Pt>](&d).is_none());
                }
            }
        )*
    };

    (UNSIGNED FROM_UINT $dec: ident, $D: ident, $($Pt: ty),*) => {
        $(
            paste::paste! {
                #[rstest(::trace)]
                #[case(0, $dec!(0))]
                #[case(1, $dec!(1))]
                #[case(10, $dec!(10))]
                #[case(100, $dec!(100))]
                #[case($Pt::MAX, $D::from($Pt::MAX))]
                #[case($Pt::MAX - 1, $D::from($Pt::MAX) - $dec!(1))]
                fn [< test_from_ $Pt >](#[case] n: $Pt, #[case] expected: $D) {
                    assert_eq!(<$D as FromPrimitive>::[< from_ $Pt>](n), Some(expected));
                }
            }
        )*
    };
    (UNSIGNED FROM_INT $dec: ident, $D: ident, $($Pt: ty),*) => {
        $(
            paste::paste! {
                #[rstest(::trace)]
                #[case(0, $dec!(0))]
                #[case(1, $dec!(1))]
                #[case(10, $dec!(10))]
                #[case(100, $dec!(100))]
                #[case($Pt::MAX, $D::try_from($Pt::MAX).unwrap())]
                #[case($Pt::MAX - 1, $D::try_from($Pt::MAX).unwrap() - $dec!(1))]
                fn [< test_from_ $Pt >](#[case] n: $Pt, #[case] expected: $D) {
                    assert_eq!(<$D as FromPrimitive>::[< from_ $Pt>](n), Some(expected));
                }

                #[rstest(::trace)]
                #[case($Pt::MIN)]
                fn [< test_from_ $Pt _negative>](#[case] n: $Pt) {
                    assert!(<$D as FromPrimitive>::[< from_ $Pt>](n).is_none());
                }
            }
        )*
    };
    (SIGNED FROM_UINT $dec: ident, $D: ident, $($Pt: ty),*) => {
        $(
            paste::paste! {
                #[rstest(::trace)]
                #[case(0, $dec!(0))]
                #[case(1, $dec!(1))]
                #[case(10, $dec!(10))]
                #[case(100, $dec!(100))]
                #[case($Pt::MAX, $D::from($Pt::MAX))]
                #[case($Pt::MAX - 1, $D::from($Pt::MAX) - $dec!(1))]
                fn [< test_from_ $Pt >](#[case] n: $Pt, #[case] expected: $D) {
                    assert_eq!(<$D as FromPrimitive>::[< from_ $Pt>](n), Some(expected));
                }
            }
        )*
    };
    (SIGNED FROM_INT $dec: ident, $D: ident, $($Pt: ty),*) => {
        $(
            paste::paste! {
                #[rstest(::trace)]
                #[case(0, $dec!(0))]
                #[case(1, $dec!(1))]
                #[case(-1, $dec!(-1))]
                #[case(10, $dec!(10))]
                #[case(-10, $dec!(-10))]
                #[case(100, $dec!(100))]
                #[case(-100, $dec!(-100))]
                #[case($Pt::MIN, $D::from($Pt::MIN))]
                #[case($Pt::MIN + 1, $D::from($Pt::MIN) + $dec!(1))]
                #[case($Pt::MAX, $D::from($Pt::MAX))]
                #[case($Pt::MAX - 1, $D::from($Pt::MAX) - $dec!(1))]
                fn [< test_from_ $Pt >](#[case] n: $Pt, #[case] expected: $D) {
                    assert_eq!(<$D as FromPrimitive>::[< from_ $Pt>](n), Some(expected));
                }
            }
        )*
    };
}

pub(crate) use test_impl;