Files
sigils/src/natural.rs

83 lines
2.1 KiB
Rust
Raw Normal View History

// SPDX-License-Identifier: Apache-2.0
// Sealed with Magistamp.
use core::ops::{Add, AddAssign, Mul, MulAssign};
use crate::number::Number;
use crate::one::One;
/// A Natural number is a counting number from one to infinity.
/// 1, 2, 3, 4, 5, 6, ...
///
/// Rust types that are in this category are:
/// u8, u16, u32, u64, u128, usize
pub trait Natural: Number + One +
Add<Output=Self> + AddAssign +
Mul<Output=Self> + MulAssign +
{
/// Attempts to subtract a number from itself.
///
/// Since subtraction isn't closed under this set (1 - 2 = -1) the trait
/// doesn't enforce that Sub and SubAssign are implemented. This function,
/// however, allows for subtraction and handles the case where the result is
/// no longer within the `Natural` numbers domain.
///
/// # Arguments
/// `rhs`: The number to subtract.
///
/// # Returns
/// `None` if the subtraction would fall below 1.
/// `Some` if their is a valid result.
///
/// # Examples
/// ```rust
/// use sigils::Natural;
///
/// let x = 3u8 as Natural;
///
/// assert_eq!(x.try_sub(2), Some(1));
/// assert_eq!(x.try_sub(7), None);
/// ```
fn try_sub(self, rhs: Self) -> Option<Self>;
/*
///
fn try_div(self, rhs: Self) -> Option<Self>;
///
fn try_rem(self, rhs: Self) -> Option<Self>;
/// Performs division and returns both the quotient and remainder.
#[inline]
fn try_div_rem(self, rhs: Self) -> Option<(Self, Self)>
{
Some((self.try_div(rhs)?, self.try_rem(rhs)?))
}
*/
}
/// A macro to make implementing the `Natural` trait easier for all the
/// base types in Rust.
macro_rules! natural_trait_impl
{
($($varType:ty),*) =>
{
$(
impl Natural for $varType
{
#[inline]
fn try_sub(self, rhs: Self) -> Option<Self>
{
self.checked_sub(rhs).filter(|x| *x >= Self::one())
}
}
)*
}
}
// Implement the Number trait for the types that are Numbers.
natural_trait_impl!(u8, u16, u32, u64, u128, usize);