Adjusted the natrual definition to now handle sub.

This neded a subtraction that would work on natural numbers where
subtraction isn't closed. This will now handle it and filter to make
sure the answer is 1 or higher.
This commit is contained in:
2026-02-26 13:14:21 -05:00
parent fbef05fcd1
commit 948ac5f297

View File

@ -1,10 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
// Sealed with Magistamp.
use core::mem::size_of;
use core::ops::{Add, Sub, Mul, Div, Rem};
use core::ops::{AddAssign, SubAssign, MulAssign, DivAssign, RemAssign};
use core::str::FromStr;
use core::ops::{Add, AddAssign, Mul, MulAssign};
use crate::number::Number;
use crate::one::One;
@ -18,15 +15,68 @@ use crate::one::One;
/// u8, u16, u32, u64, u128, usize
pub trait Natural: Number + One +
Add<Output=Self> + AddAssign +
Sub<Output=Self> + SubAssign +
Mul<Output=Self> + MulAssign +
Div<Output=Self> + DivAssign +
Rem<Output=Self> + RemAssign
{
/// 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 div_rem(self, rhs: Self) -> (Self, Self)
fn try_div_rem(self, rhs: Self) -> Option<(Self, Self)>
{
(self / rhs, self % rhs)
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);