use ::number::Number; use ::one::One; use ::zero::Zero; /// A trait that defines what is required to be considered /// an Integer. [List of types of numbers][1] /// /// This is meant to have all the similarities between /// [u8][2], [u16][3], [u32][4], [u64][5], [usize][6], /// [i8][7], [i16][8], [i32][9], [i64][10], [isize][11]. /// Most of the comments and documentation were taken /// from the [rust-lang std docs][12]. /// /// [1]: https://en.wikipedia.org/wiki/List_of_types_of_numbers /// [2]: https://doc.rust-lang.org/std/primitive.u8.html /// [3]: https://doc.rust-lang.org/std/primitive.u16.html /// [4]: https://doc.rust-lang.org/std/primitive.u32.html /// [5]: https://doc.rust-lang.org/std/primitive.u64.html /// [6]: https://doc.rust-lang.org/std/primitive.usize.html /// [7]: https://doc.rust-lang.org/std/primitive.i8.html /// [8]: https://doc.rust-lang.org/std/primitive.i16.html /// [9]: https://doc.rust-lang.org/std/primitive.i32.html /// [10]: https://doc.rust-lang.org/std/primitive.i64.html /// [11]: https://doc.rust-lang.org/std/primitive.isize.html /// [12]: https://doc.rust-lang.org/std/index.html pub trait Integer: Number { /// Computes the absolute value of `self`. /// Returns ::MIN if the number is ::MIN. /// /// ``` /// use sigils::{Integer, Number}; /// /// let x = -75i32; /// let y = 84i16; /// /// assert_eq!(x.abs(), 75i32); /// assert_eq!(y.abs(), 84i16); /// assert_eq!(u8::MIN.abs(), u8::MIN); /// ``` fn abs(self) -> Self; /// Returns a number that represents the sign of `self`. /// /// - `1` if the number is positive, `(0, MAX]` /// - `0` if the number is zero, `[0]` /// - `-1` if the number is negative, `[MIN, 0)` /// /// ``` /// use sigils::Integer; /// /// let e = -3i32; /// let f = 3u64; /// let g = 0i64; /// /// assert_eq!(e.signum(), -1i32); /// assert_eq!(f.signum(), 1u64); /// assert_eq!(g.signum(), 0i64); /// ``` fn signum(self) -> Self; /// Returns `true` if `self` is positive and /// 'false' if the Integer is zero or negative. /// (0, MAX] /// /// ``` /// use sigils::Integer; /// /// let e: i32; /// let f: i32; /// let g: u64; /// /// e = 5i32; /// f = -33i32; /// g = 782u64; /// /// assert!(e.is_sign_positive() == true); /// assert!(f.is_sign_positive() == false); /// assert!(g.is_sign_positive() == true); /// ``` fn is_sign_positive(self) -> bool; /// Returns `true` if `self` is negative and /// 'false' if the Integer is zero or positive. /// [MIN, 0) /// /// ``` /// use sigils::Integer; /// /// let e: i32; /// let f: i32; /// let g: u64; /// /// e = 5i32; /// f = -33i32; /// g = 782u64; /// /// assert!(e.is_sign_negative() == false); /// assert!(f.is_sign_negative() == true); /// assert!(g.is_sign_negative() == false); /// ``` fn is_sign_negative(self) -> bool; } // Create a macro to ease typing and reading. /// A macro to make implementing the trait easier for all the /// base integer signed types in rust. macro_rules! signed_trait_impl { ($traitName: ident for $($varType: ty)*) => ($( impl $traitName for $varType { fn abs(self) -> Self { if self < Self::zero() { -self } else { self } } fn signum(self) -> Self { if self.is_sign_negative() == true { -1 } else if self.is_sign_positive() == true { Self::one() } else { Self::zero() } } fn is_sign_negative(self) -> bool { self < Self::zero() } fn is_sign_positive(self) -> bool { self > Self::zero() } } )*) } /// A macro to make implementing the trait easier for all the /// base integer unsigned types in rust. macro_rules! unsigned_trait_impl { ($traitName: ident for $($varType: ty)*) => ($( impl $traitName for $varType { fn abs(self) -> Self { self } fn signum(self) -> Self { if self == Self::zero() { Self::zero() } else { Self::one() } } fn is_sign_negative(self) -> bool { false } fn is_sign_positive(self) -> bool { self > Self::zero() } } )*) } // Implement the trait for the types that are Integers. signed_trait_impl!(Integer for i8 i16 i32 i64 isize); unsigned_trait_impl!(Integer for u8 u16 u32 u64 usize);