use crate::I256;
use crate::fmt::{HEX_DIGITS, LOWER, hex_digits};
use core::fmt;
#[cfg(feature = "fmt")]
use crate::fmt::{DEC_DIGITS, UPPER, dec_digits};
impl fmt::Debug for I256 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut buf = [0u8; HEX_DIGITS];
if self.is_negative() {
f.write_str("-")?;
}
f.write_str("0x")?;
f.write_str(hex_digits(&self.unsigned_abs(), &mut buf, &LOWER))
}
}
#[cfg(feature = "fmt")]
impl fmt::LowerHex for I256 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut buf = [0u8; HEX_DIGITS];
let digits = hex_digits(&self.cast_unsigned(), &mut buf, &LOWER);
f.pad_integral(true, "0x", digits)
}
}
#[cfg(feature = "fmt")]
impl fmt::UpperHex for I256 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut buf = [0u8; HEX_DIGITS];
let digits = hex_digits(&self.cast_unsigned(), &mut buf, &UPPER);
f.pad_integral(true, "0x", digits)
}
}
#[cfg(feature = "fmt")]
impl fmt::Display for I256 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut buf = [0u8; DEC_DIGITS];
let digits = dec_digits(&self.unsigned_abs(), &mut buf);
f.pad_integral(!self.is_negative(), "", digits)
}
}
#[cfg(feature = "fmt")]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ParseI256Error {
Empty,
InvalidDigit,
Overflow,
}
#[cfg(feature = "fmt")]
impl fmt::Display for ParseI256Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match self {
Self::Empty => "cannot parse an empty string as I256",
Self::InvalidDigit => "invalid decimal digit",
Self::Overflow => "value does not fit in a signed 256-bit integer",
})
}
}
#[cfg(all(feature = "fmt", feature = "std"))]
impl std::error::Error for ParseI256Error {}
#[cfg(feature = "fmt")]
impl core::str::FromStr for I256 {
type Err = ParseI256Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
use crate::{ParseU256Error, U256};
let (negative, digits) = match s.as_bytes().first() {
None => return Err(ParseI256Error::Empty),
Some(b'-') => (true, &s[1..]),
Some(b'+') => (false, &s[1..]),
_ => (false, s),
};
if digits.is_empty() {
return Err(ParseI256Error::InvalidDigit);
}
let magnitude = U256::from_str(digits).map_err(|e| match e {
ParseU256Error::Empty => ParseI256Error::Empty,
ParseU256Error::InvalidDigit => ParseI256Error::InvalidDigit,
ParseU256Error::Overflow => ParseI256Error::Overflow,
})?;
let limit = if negative {
U256::ONE.wrapping_shl(255)
} else {
Self::MAX.cast_unsigned()
};
if magnitude > limit {
return Err(ParseI256Error::Overflow);
}
Ok(if negative {
magnitude.wrapping_neg().cast_signed()
} else {
magnitude.cast_signed()
})
}
}