light_ranged_integers 0.1.1

A Rust library similar to ranged_integers, a bit limited to work on stable rust
Documentation
/*
Copyright © 2024 - Massimo Gismondi

This file is part of light-ranged-integers.

light-ranged-integers is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

light-ranged-integers is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with light-ranged-integers.  If not, see <http://www.gnu.org/licenses/>.
*/

use crate::op_mode::{Clamp, Panic, Wrap};
use crate::*;
use paste::paste;

macro_rules! test_generator {
    ($i:ty) => {
        paste! {
            /// Verify Ranged type size is the same as the pure int type
            #[test]
            fn [<detect_size_ $i>]()
            {
                assert_eq!(
                    std::mem::size_of::<[<Ranged $i:upper>]>(),
                    std::mem::size_of::<$i>()
                )
            }

            /// Check Clamping works
            #[test]
            fn [<check_clamping_ $i>]()
            {
                assert!(
                    [<Ranged $i:upper>]::<{$i::MIN}, {$i::MAX}, Clamp>::new($i::MAX)
                        + [<Ranged $i:upper>]::new(1)
                    ==
                        $i::MAX
                );
                assert!(
                    [<Ranged $i:upper>]::<{$i::MIN}, {$i::MAX}, Clamp>::new($i::MIN)
                        - [<Ranged $i:upper>]::new(1)
                    ==
                        $i::MIN
                );
                assert!(
                    [<Ranged $i:upper>]::<{$i::MIN}, {$i::MAX}, Clamp>::new($i::MAX/2)
                        + [<Ranged $i:upper>]::new($i::MAX)
                    ==
                        $i::MAX
                );
                assert_eq!(
                    [<Ranged $i:upper>]::<{$i::MIN}, {$i::MAX}, Clamp>::new($i::MAX/2)
                        - [<Ranged $i:upper>]::new($i::MAX) - [<Ranged $i:upper>]::new($i::MAX)
                    ,
                        $i::MIN
                );

                // Smaller ranges
                assert!(
                    [<Ranged $i:upper>]::<{$i::MIN/2}, {$i::MAX/2}, Clamp>::new($i::MAX)
                        + [<Ranged $i:upper>]::new($i::MAX)
                    ==
                        $i::MAX/2
                );
                assert!(
                    [<Ranged $i:upper>]::<{$i::MIN/2}, {$i::MAX/2}, Clamp>::new($i::MIN)
                        - [<Ranged $i:upper>]::new($i::MAX)
                    ==
                        $i::MIN/2
                );

                // Small interval
                assert!(
                    [<Ranged $i:upper>]::<0, 1, Clamp>::new($i::MAX)
                        + [<Ranged $i:upper>]::new($i::MAX)
                    ==
                        1
                );
                assert!(
                    [<Ranged $i:upper>]::<0,1, Clamp>::new($i::MIN)
                        - [<Ranged $i:upper>]::new($i::MAX)
                    ==
                        0
                );
            }
        }
    };
}

test_generator!(u8);
test_generator!(i8);
test_generator!(u16);
test_generator!(i16);
test_generator!(u32);
test_generator!(i32);
test_generator!(u64);
test_generator!(i64);

#[test]
fn from_trait()
{
    let _: RangedI16<0, 15> = 5.into();
}

#[test]
fn sum()
{
    assert_eq!(RangedU16::<2, 5, Clamp>::new(0).inner(), 2);
    assert_eq!(RangedU16::<2, 5, Clamp>::new(500).inner(), 5);

    assert_eq!(RangedU16::<2, 500, Clamp>::new(500) + 5u16, 500)
}

#[test]
fn const_rangeds()
{
    let a: RangedU8<0, 10, Wrap> = RangedU8::const_new::<5>();
    let b: RangedU8<0, 10, Wrap> = RangedU8::const_new::<5>();

    use const_ranged::ConstRangedU8;
    ConstRangedU8::<0, 20, 10>::new().limit::<0, 30>();

    // const A: ConstRangedU8<10,50,10> = ConstRangedU8::new();
    // const B: ConstRangedU8<10,50,10> = ConstRangedU8::new();
    // use paste::paste;
    // macro_rules! r {
    //     (
    //         $wrapped_type:ty, [$min:expr, $max:expr], $value:expr
    //     ) => {
    //         paste!{
    //             [<ConstRanged $wrapped_type:upper>]::<$min, $max,{$value}>::new()
    //         }
    //     };
    // }
    // const Z: ConstRangedU8<10,50,45> = ConstRangedU8::new();

    // assert_eq!(
    //     r!(u8, [0,20], A.inner()+B.inner()).inner(),
    //     r!(u8, [0,20], 20).inner()
    // );

    // ConstRangedU8::<10,50,20>::new();

    // const C: ConstRangedU8<10,50,{A.inner()+B.inner()}> = ConstRangedU8::new();
}

#[test]
fn result_range()
{
    let n1 = RangedU16::<1, 6, Clamp>::new(3);
    assert_eq!(n1, 3);
    let n2 = RangedU16::<1, 6, Clamp>::new(10);
    assert_eq!(n2, 6);

    assert_eq!(n1 + n2, 6);

    let mut n3 = RangedU16::<1, 6, Wrap>::new(3);
    n3 += 1;
}

#[test]
fn partial_ord_eq()
{
    let n1 = RangedU16::<1, 6, Clamp>::new(1);
    let n2 = RangedU16::<1, 6, Clamp>::new(1);
    let n3 = RangedU16::<1, 6, Clamp>::new(6);
    assert!(n1 == n1);
    assert!(n1 == n2);
    assert!(n3 > n2);
}

#[test]
fn limit_expand()
{
    let n1 = RangedU16::<1, 6, Clamp>::new(3);
    assert_eq!(n1, 3);
    let n2 = RangedU16::<1, 6, Clamp>::new(10);
    assert_eq!(n2, 6);

    assert_eq!(n1.limit::<1, 15>() + n2.limit::<1, 15>(), 9);
}

#[test]
#[should_panic]
fn outside_range_low()
{
    RangedU16::<1, 6, Panic>::new(0);
}

#[test]
#[should_panic]
fn outside_range_high()
{
    RangedU16::<1, 6, Panic>::new(7);
}