light_ranged_integers 0.1.3

Ranged integers for stable Rust compiler, zero-dependencies and no unsafe code.
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/>.
*/

//! A collection of modes to use during computation, setting how to apply the range limit

/// This mode will panic the program
/// if the number is outside the interval
#[derive(Debug, Clone, Copy)]
pub struct Panic;
/// This mode will clamp the value inside the provided limits
#[derive(Debug, Clone, Copy)]
pub struct Clamp;

/// This mode will wrap the result to make it fit the range again
#[derive(Debug, Clone, Copy)]
pub struct Wrap;

/// A marker trait to identify
/// which structs can be used as a OpMode
pub trait OpModeExt:
    BringInRange<u8>
    + BringInRange<u16>
    + BringInRange<u32>
    + BringInRange<u64>
    + BringInRange<i8>
    + BringInRange<i16>
    + BringInRange<i32>
    + BringInRange<i64>
    + Clone
    + Copy
{
}
impl OpModeExt for Panic {}
impl OpModeExt for Clamp {}
impl OpModeExt for Wrap {}

/// Useful to unify operations to bring a value in its intended range, depending on the selected mode
pub trait BringInRange<N>
{
    fn bring_in_range(v: N, min: N, max: N) -> N;
}

macro_rules! bring_in_range_impl {
    ($i:ty) => {
        impl BringInRange<$i> for Panic
        {
            fn bring_in_range(v: $i, min: $i, max: $i) -> $i
            {
                assert!(v >= min);
                assert!(v <= max);
                v
            }
        }
        impl BringInRange<$i> for Clamp
        {
            fn bring_in_range(v: $i, min: $i, max: $i) -> $i
            {
                v.clamp(min, max)
            }
        }
    };
}

bring_in_range_impl!(u8);
bring_in_range_impl!(u16);
bring_in_range_impl!(u32);
bring_in_range_impl!(u64);

bring_in_range_impl!(i8);
bring_in_range_impl!(i16);
bring_in_range_impl!(i32);
bring_in_range_impl!(i64);