2026-02-12 19:21:53 -05:00
|
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
|
// Sealed with Magistamp.
|
|
|
|
|
|
2026-02-26 13:14:21 -05:00
|
|
|
use core::ops::{Add, AddAssign, Mul, MulAssign};
|
2026-02-12 19:21:53 -05:00
|
|
|
|
|
|
|
|
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 +
|
|
|
|
|
{
|
2026-02-26 13:14:21 -05:00
|
|
|
/// 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>;
|
|
|
|
|
|
2026-02-12 19:21:53 -05:00
|
|
|
/// Performs division and returns both the quotient and remainder.
|
|
|
|
|
#[inline]
|
2026-02-26 13:14:21 -05:00
|
|
|
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),*) =>
|
2026-02-12 19:21:53 -05:00
|
|
|
{
|
2026-02-26 13:14:21 -05:00
|
|
|
$(
|
|
|
|
|
impl Natural for $varType
|
|
|
|
|
{
|
|
|
|
|
#[inline]
|
|
|
|
|
fn try_sub(self, rhs: Self) -> Option<Self>
|
|
|
|
|
{
|
|
|
|
|
self.checked_sub(rhs).filter(|x| *x >= Self::one())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
)*
|
2026-02-12 19:21:53 -05:00
|
|
|
}
|
|
|
|
|
}
|
2026-02-26 13:14:21 -05:00
|
|
|
|
|
|
|
|
// Implement the Number trait for the types that are Numbers.
|
|
|
|
|
natural_trait_impl!(u8, u16, u32, u64, u128, usize);
|