#
enum_ordinalize_derive/
int128.rs

    1use core::{
    2    cmp::Ordering,
    3    fmt::{self, Display, Formatter},
    4    num::ParseIntError,
    5    ops::Neg,
    6    str::FromStr,
    7};
    8
    9#[derive(Debug, Copy, Eq, Clone)]
    10pub(crate) enum Int128 {
    11    Signed(i128),
    12    Unsigned(u128),
    13}
    14
    15impl PartialEq for Int128 {
    16    #[inline]
    17    fn eq(&self, other: &Int128) -> bool {
    18        match self {
    19            Self::Signed(i) => match other {
    20                Self::Signed(i2) => i.eq(i2),
    21                Self::Unsigned(u2) => {
    22                    if i.is_negative() {
    23                        false
    24                    } else {
    25                        (*i as u128).eq(u2)
    26                    }
    27                },
    28            },
    29            Self::Unsigned(u) => match other {
    30                Self::Signed(i2) => {
    31                    if i2.is_negative() {
    32                        false
    33                    } else {
    34                        u.eq(&(*i2 as u128))
    35                    }
    36                },
    37                Self::Unsigned(u2) => u.eq(u2),
    38            },
    39        }
    40    }
    41}
    42
    43impl PartialOrd for Int128 {
    44    #[inline]
    45    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
    46        Some(self.cmp(other))
    47    }
    48}
    49
    50impl Ord for Int128 {
    51    #[inline]
    52    fn cmp(&self, other: &Self) -> Ordering {
    53        match self {
    54            Self::Signed(i) => match other {
    55                Self::Signed(i2) => i.cmp(i2),
    56                Self::Unsigned(u2) => {
    57                    if i.is_negative() {
    58                        Ordering::Less
    59                    } else {
    60                        (*i as u128).cmp(u2)
    61                    }
    62                },
    63            },
    64            Self::Unsigned(u) => match other {
    65                Self::Signed(i2) => {
    66                    if i2.is_negative() {
    67                        Ordering::Greater
    68                    } else {
    69                        u.cmp(&(*i2 as u128))
    70                    }
    71                },
    72                Self::Unsigned(u2) => u.cmp(u2),
    73            },
    74        }
    75    }
    76}
    77
    78impl Display for Int128 {
    79    #[inline]
    80    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
    81        match self {
    82            Self::Signed(i) => Display::fmt(i, f),
    83            Self::Unsigned(u) => Display::fmt(u, f),
    84        }
    85    }
    86}
    87
    88impl Default for Int128 {
    89    #[inline]
    90    fn default() -> Self {
    91        Self::ZERO
    92    }
    93}
    94
    95impl Int128 {
    96    pub(crate) const ZERO: Self = Self::Unsigned(0);
    97}
    98
    99macro_rules! impl_from_signed {
    100    (@inner $t: ty) => {
    101        impl From<$t> for Int128 {
    102            #[inline]
    103            fn from(value: $t) -> Self {
    104                Int128::Signed(value as i128)
    105            }
    106        }
    107    };
    108    ($($t: ty),+ $(,)*) => {
    109        $(
    110            impl_from_signed!(@inner $t);
    111        )*
    112    };
    113}
    114
    115impl_from_signed!(i8, i16, i32, i64, i128, isize);
    116
    117impl FromStr for Int128 {
    118    type Err = ParseIntError;
    119
    120    #[inline]
    121    fn from_str(s: &str) -> Result<Self, Self::Err> {
    122        if s.starts_with('-') {
    123            Ok(Self::Signed(s.parse()?))
    124        } else {
    125            Ok(Self::Unsigned(s.parse()?))
    126        }
    127    }
    128}
    129
    130impl Neg for Int128 {
    131    type Output = Int128;
    132
    133    fn neg(self) -> Self::Output {
    134        match self {
    135            Self::Signed(i) => {
    136                if i == i128::MIN {
    137                    Self::Unsigned(1 << 127)
    138                } else {
    139                    Self::Signed(-i)
    140                }
    141            },
    142            Self::Unsigned(u) => match u.cmp(&(1 << 127)) {
    143                Ordering::Equal => Self::Signed(i128::MIN),
    144                Ordering::Less => Self::Signed(-(u as i128)),
    145                Ordering::Greater => panic!("-{} is experiencing an overflow", u),
    146            },
    147        }
    148    }
    149}
    150
    151impl Int128 {
    152    #[inline]
    153    pub(crate) fn inc(&mut self) {
    154        match self {
    155            Self::Signed(i) => {
    156                if *i == i128::MAX {
    157                    *self = Self::Unsigned(1 << 127)
    158                } else {
    159                    *i += 1;
    160                }
    161            },
    162            Self::Unsigned(u) => {
    163                *u = u.saturating_add(1);
    164            },
    165        }
    166    }
    167}