#[cfg(feature = "serde")]
use serde::{Serialize,Deserialize};
use std::num::*;
use crate::macros::*;
use crate::constants::*;
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "bincode", derive(bincode::Encode, bincode::Decode))]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct Int(i64, Buffer);
impl Int {
impl_common!(i64);
impl_const!();
impl_isize!();
impl_buffer!(MAX_BUF_LEN, UNKNOWN_BUFFER, UNKNOWN.len());
#[inline]
pub const fn zero() -> Self {
Self(0, Buffer::zero())
}
#[inline]
pub const fn unknown() -> Self {
Self(0, Buffer::unknown())
}
}
macro_rules! impl_i {
($( $from:ty ),*) => {
$(
impl From<$from> for Int {
fn from(int: $from) -> Self {
let i = int as i64;
Self(i, Buffer::from_i(i))
}
}
)*
}
}
impl_i!(i8,i16,i32,i64,isize,u8,u16,u32);
macro_rules! impl_noni {
($( $from:ty ),*) => {
$(
impl From<$from> for Int {
fn from(int: $from) -> Self {
let i = int.get() as i64;
Self(i, Buffer::from_i(i))
}
}
)*
}
}
impl_noni! {
NonZeroI8,NonZeroI16,NonZeroI32,NonZeroI64,NonZeroIsize,
&NonZeroI8,&NonZeroI16,&NonZeroI32,&NonZeroI64,&NonZeroIsize
}
macro_rules! impl_f {
($from:ty) => {
impl From<$from> for Int {
fn from(float: $from) -> Self {
handle_nan_runtime!(float);
let i = float as i64;
Self(i, Buffer::from_i(i))
}
}
}
}
impl_f!(f32);
impl_f!(f64);
macro_rules! impl_try {
($( $from:ty ),*) => {
$(
impl TryFrom<$from> for Int {
type Error = Self;
fn try_from(num: $from) -> Result<Self, Self> {
match i64::try_from(num) {
Ok(i) => Ok(Self(i, Buffer::from_i(i))),
_ => Err(Self::unknown()),
}
}
}
)*
}
}
impl_try!(u64,usize);
macro_rules! impl_noni {
($( $from:ty ),*) => {
$(
impl TryFrom<$from> for Int {
type Error = Self;
fn try_from(num: $from) -> Result<Self, Self> {
match i64::try_from(num.get()) {
Ok(i) => Ok(Self(i, Buffer::from_i(i))),
_ => Err(Self::unknown()),
}
}
}
)*
}
}
impl_noni! {
NonZeroU8,NonZeroU16,NonZeroU32,NonZeroU64,NonZeroUsize,
&NonZeroU8,&NonZeroU16,&NonZeroU32,&NonZeroU64,&NonZeroUsize
}
impl_math!(Int, i64);
impl_traits!(Int, i64);
buffer!(MAX_BUF_LEN, UNKNOWN_NUM_BUFFER, UNKNOWN.len());
impl Buffer {
#[inline(always)]
const fn zero() -> Self {
Self {
buf: ZERO_NUM_BUFFER,
len: 1,
}
}
#[inline(always)]
fn from_i(i: i64) -> Self {
let (buf, len) = crate::buf::from_i(i);
Self { buf, len }
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn unsigned() {
assert!(Int::from(1_000_i64) == "1,000");
assert!(Int::from(65_535_i64) == "65,535");
assert!(Int::from(65_536_i64) == "65,536");
assert!(Int::from(100_000_i64) == "100,000");
assert!(Int::from(1_000_000_i64) == "1,000,000");
assert!(Int::from(10_000_000_i64) == "10,000,000");
assert!(Int::from(100_000_000_i64) == "100,000,000");
assert!(Int::from(1_000_000_000_i64) == "1,000,000,000");
assert!(Int::from(4_294_967_295_i64) == "4,294,967,295");
assert!(Int::from(4_294_967_296_i64) == "4,294,967,296");
assert!(Int::from(10_000_000_000_i64) == "10,000,000,000");
assert!(Int::from(100_000_000_000_i64) == "100,000,000,000");
assert!(Int::from(1_000_000_000_000_i64) == "1,000,000,000,000");
assert!(Int::from(10_000_000_000_000_i64) == "10,000,000,000,000");
assert!(Int::from(100_000_000_000_000_i64) == "100,000,000,000,000");
assert!(Int::from(1_000_000_000_000_000_i64) == "1,000,000,000,000,000");
assert!(Int::from(10_000_000_000_000_000_i64) == "10,000,000,000,000,000");
}
#[test]
fn int() {
assert!(Int::from(-1_000_i64) == "-1,000");
assert!(Int::from(-65_535_i64) == "-65,535");
assert!(Int::from(-65_536_i64) == "-65,536");
assert!(Int::from(-100_000_i64) == "-100,000");
assert!(Int::from(-1_000_000_i64) == "-1,000,000");
assert!(Int::from(-10_000_000_i64) == "-10,000,000");
assert!(Int::from(-100_000_000_i64) == "-100,000,000");
assert!(Int::from(-1_000_000_000_i64) == "-1,000,000,000");
assert!(Int::from(-4_294_967_295_i64) == "-4,294,967,295");
assert!(Int::from(-4_294_967_296_i64) == "-4,294,967,296");
assert!(Int::from(-10_000_000_000_i64) == "-10,000,000,000");
assert!(Int::from(-100_000_000_000_i64) == "-100,000,000,000");
assert!(Int::from(-1_000_000_000_000_i64) == "-1,000,000,000,000");
assert!(Int::from(-10_000_000_000_000_i64) == "-10,000,000,000,000");
assert!(Int::from(-100_000_000_000_000_i64) == "-100,000,000,000,000");
assert!(Int::from(-1_000_000_000_000_000_i64) == "-1,000,000,000,000,000");
assert!(Int::from(-10_000_000_000_000_000_i64) == "-10,000,000,000,000,000");
assert!(Int::from(i64::MIN) == "-9,223,372,036,854,775,808");
assert!(Int::from(i64::MAX) == "9,223,372,036,854,775,807");
}
#[test]
fn float() {
assert!(Int::from(-1_000.0) == "-1,000");
assert!(Int::from(-65_535.0) == "-65,535");
assert!(Int::from(-65_536.0) == "-65,536");
assert!(Int::from(-100_000.0) == "-100,000");
assert!(Int::from(-1_000_000.0) == "-1,000,000");
assert!(Int::from(-10_000_000.0) == "-10,000,000");
assert!(Int::from(-100_000_000.0) == "-100,000,000");
assert!(Int::from(-1_000_000_000.0) == "-1,000,000,000");
assert!(Int::from(-4_294_967_295.0) == "-4,294,967,295");
assert!(Int::from(-4_294_967_296.0) == "-4,294,967,296");
assert!(Int::from(-10_000_000_000.0) == "-10,000,000,000");
assert!(Int::from(-100_000_000_000.0) == "-100,000,000,000");
assert!(Int::from(-1_000_000_000_000.0) == "-1,000,000,000,000");
assert!(Int::from(-10_000_000_000_000.0) == "-10,000,000,000,000");
assert!(Int::from(-100_000_000_000_000.0) == "-100,000,000,000,000");
assert!(Int::from(-1_000_000_000_000_000.0) == "-1,000,000,000,000,000");
assert!(Int::from(i64::MIN as f64) == "-9,223,372,036,854,775,808");
assert!(Int::from(i64::MAX as f64) == "9,223,372,036,854,775,807");
}
#[test]
fn special() {
assert!(Int::from(f64::NAN) == crate::UNKNOWN);
assert!(Int::from(f64::INFINITY) == crate::UNKNOWN);
assert!(Int::from(f64::NEG_INFINITY) == crate::UNKNOWN);
}
}