use crate::decimal::{Buf, Decimal, MAX_PRECISION, MAX_SCALE, MIN_SCALE};
use crate::u256::POWERS_10;
use crate::DecimalConvertError;
use std::convert::TryFrom;
pub(crate) const MAX_I128_REPR: i128 = 99_9999_9999_9999_9999_9999_9999_9999_9999_9999_i128;
macro_rules! impl_from_small_int {
($ty: ty) => {
impl From<$ty> for Decimal {
#[inline]
fn from(val: $ty) -> Self {
unsafe { Decimal::from_raw_parts(val as u128, 0, false) }
}
}
};
(SIGNED $ty: ty) => {
impl From<$ty> for Decimal {
#[inline]
fn from(val: $ty) -> Decimal {
let (int_val, negative) = if val < 0 {
(-(val as i128) as u128, true)
} else {
(val as u128, false)
};
unsafe { Decimal::from_raw_parts(int_val, 0, negative) }
}
}
};
($($ty: ty), * $(,)?) => {
$(impl_from_small_int!($ty);)*
};
(SIGNED $($ty: ty), * $(,)?) => {
$(impl_from_small_int!(SIGNED $ty);)*
}
}
impl_from_small_int!(u8, u16, u32, u64, usize);
impl_from_small_int!(SIGNED i8, i16, i32, i64, isize);
impl From<bool> for Decimal {
#[inline]
fn from(b: bool) -> Self {
if b {
Decimal::ONE
} else {
Decimal::ZERO
}
}
}
impl TryFrom<i128> for Decimal {
type Error = DecimalConvertError;
#[inline]
fn try_from(val: i128) -> std::result::Result<Self, Self::Error> {
if !(-MAX_I128_REPR..=MAX_I128_REPR).contains(&val) {
Err(DecimalConvertError::Overflow)
} else {
let (int_val, negative) = if val < 0 {
(val.wrapping_neg() as u128, true)
} else {
(val as u128, false)
};
Ok(unsafe { Decimal::from_raw_parts(int_val, 0, negative) })
}
}
}
impl TryFrom<u128> for Decimal {
type Error = DecimalConvertError;
#[inline]
fn try_from(value: u128) -> std::result::Result<Self, Self::Error> {
if value > MAX_I128_REPR as u128 {
Err(DecimalConvertError::Overflow)
} else {
Ok(unsafe { Decimal::from_raw_parts(value, 0, false) })
}
}
}
impl TryFrom<f32> for Decimal {
type Error = DecimalConvertError;
#[inline]
fn try_from(value: f32) -> std::result::Result<Self, Self::Error> {
if value.is_infinite() {
return Err(DecimalConvertError::Overflow);
}
if value.is_nan() {
return Err(DecimalConvertError::Invalid);
}
debug_assert!(value.is_finite());
let raw = value.to_bits();
let negative = (raw >> 31) == 1;
let biased_exponent = ((raw >> 23) & 0xFF) as i32;
let mantissa = raw & 0x007F_FFFF;
if biased_exponent == 0 && mantissa == 0 {
return Ok(Decimal::ZERO);
}
let mut exponent2 = biased_exponent - 127;
let mut bits = mantissa as u128;
if biased_exponent == 0 {
exponent2 += 1;
} else {
bits |= 0x0080_0000;
}
exponent2 -= 23;
match base2_to_decimal::<false>(bits, exponent2, negative) {
Some(dec) => Ok(dec),
None => Err(DecimalConvertError::Overflow),
}
}
}
impl TryFrom<f64> for Decimal {
type Error = DecimalConvertError;
#[inline]
fn try_from(value: f64) -> std::result::Result<Self, Self::Error> {
if value.is_infinite() {
return Err(DecimalConvertError::Overflow);
}
if value.is_nan() {
return Err(DecimalConvertError::Invalid);
}
debug_assert!(value.is_finite());
let raw = value.to_bits();
let negative = (raw >> 63) == 1;
let biased_exponent = ((raw >> 52) & 0x7FF) as i32;
let mantissa = raw & 0x000F_FFFF_FFFF_FFFF;
if biased_exponent == 0 && mantissa == 0 {
return Ok(Decimal::ZERO);
}
let mut exponent2 = biased_exponent - 1023;
let mut bits = mantissa as u128;
if biased_exponent == 0 {
exponent2 += 1;
} else {
bits |= 0x0010_0000_0000_0000;
}
exponent2 -= 52;
match base2_to_decimal::<true>(bits, exponent2, negative) {
Some(dec) => Ok(dec),
None => Err(DecimalConvertError::Overflow),
}
}
}
fn base2_to_decimal<const IS_F64: bool>(bits: u128, exponent2: i32, negative: bool) -> Option<Decimal> {
const F32_DP: u128 = 9_9999_9999_u128;
const F64_DP: u128 = 9_9999_9999_9999_9999_u128;
let mut exponent5 = -exponent2;
let mut exponent10 = exponent2;
let mut bits = bits;
while exponent5 > 0 {
if bits & 0x1 == 0 {
exponent10 += 1;
exponent5 -= 1;
bits >>= 1;
} else {
exponent5 -= 1;
let temp = bits.checked_mul(5);
match temp {
Some(prod) => {
bits = prod
}
None => {
exponent10 += 1;
bits >>= 1;
}
}
}
}
while exponent5 < 0 {
if bits & 0x8000_0000_0000_0000_0000_0000_0000_0000 == 0 {
exponent10 -= 1;
exponent5 += 1;
bits <<= 1;
} else {
exponent5 += 1;
bits /= 5;
}
}
while exponent10 > -MIN_SCALE as i32 {
match bits.checked_mul(10) {
Some(prod) => {
if prod <= MAX_I128_REPR as u128 {
bits *= 10;
exponent10 -= 1;
} else {
return None;
}
}
None => {
return None;
}
}
}
while exponent10 < -MAX_SCALE as i32 {
let rem10 = bits % 10;
bits /= 10;
exponent10 += 1;
if bits == 0 {
exponent10 = 0;
} else if rem10 >= 5 {
bits += 1;
}
}
let mut rem10 = 0;
if IS_F64 {
while exponent10 < -MIN_SCALE as i32 && bits > F64_DP {
rem10 = bits % 10;
bits /= 10;
exponent10 += 1;
}
} else {
while exponent10 < -MIN_SCALE as i32 && bits > F32_DP {
rem10 = bits % 10;
bits /= 10;
exponent10 += 1;
}
}
if rem10 >= 5 {
bits += 1;
}
while exponent10 < -MIN_SCALE as i32 {
let remainder = bits % 10;
if remainder == 0 {
exponent10 += 1;
bits /= 10;
} else {
break;
}
}
Some(unsafe { Decimal::from_parts_unchecked(bits, -exponent10 as i16, negative) })
}
impl From<&Decimal> for f32 {
#[inline]
fn from(val: &Decimal) -> Self {
f64::from(val) as f32
}
}
impl From<Decimal> for f32 {
#[inline]
fn from(val: Decimal) -> Self {
f32::from(&val)
}
}
impl From<&Decimal> for f64 {
#[allow(clippy::comparison_chain)]
#[inline]
fn from(val: &Decimal) -> Self {
const POWERS_10: [f64; MAX_SCALE as usize + MAX_PRECISION as usize] = [
1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18,
1e19, 1e20, 1e21, 1e22, 1e23, 1e24, 1e25, 1e26, 1e27, 1e28, 1e29, 1e30, 1e31, 1e32, 1e33, 1e34, 1e35, 1e36,
1e37, 1e38, 1e39, 1e40, 1e41, 1e42, 1e43, 1e44, 1e45, 1e46, 1e47, 1e48, 1e49, 1e50, 1e51, 1e52, 1e53, 1e54,
1e55, 1e56, 1e57, 1e58, 1e59, 1e60, 1e61, 1e62, 1e63, 1e64, 1e65, 1e66, 1e67, 1e68, 1e69, 1e70, 1e71, 1e72,
1e73, 1e74, 1e75, 1e76, 1e77, 1e78, 1e79, 1e80, 1e81, 1e82, 1e83, 1e84, 1e85, 1e86, 1e87, 1e88, 1e89, 1e90,
1e91, 1e92, 1e93, 1e94, 1e95, 1e96, 1e97, 1e98, 1e99, 1e100, 1e101, 1e102, 1e103, 1e104, 1e105, 1e106,
1e107, 1e108, 1e109, 1e110, 1e111, 1e112, 1e113, 1e114, 1e115, 1e116, 1e117, 1e118, 1e119, 1e120, 1e121,
1e122, 1e123, 1e124, 1e125, 1e126, 1e127, 1e128, 1e129, 1e130, 1e131, 1e132, 1e133, 1e134, 1e135, 1e136,
1e137, 1e138, 1e139, 1e140, 1e141, 1e142, 1e143, 1e144, 1e145, 1e146, 1e147, 1e148, 1e149, 1e150, 1e151,
1e152, 1e153, 1e154, 1e155, 1e156, 1e157, 1e158, 1e159, 1e160, 1e161, 1e162, 1e163, 1e164, 1e165, 1e166,
1e167,
];
let n = val.normalize();
if n.int_val() <= 9007199254740992 {
let mut v = n.int_val() as f64;
if n.scale() > 0 {
v /= POWERS_10[n.scale() as usize];
} else if n.scale() < 0 {
v *= POWERS_10[-n.scale() as usize];
}
if n.is_sign_negative() {
v = -v;
}
v
} else {
let mut buf = Buf::new();
val.fmt_internal(true, false, false, None, &mut buf)
.expect("failed to format decimal");
let str = unsafe { std::str::from_utf8_unchecked(&*buf) };
fast_float::parse(str).unwrap()
}
}
}
impl From<Decimal> for f64 {
#[inline]
fn from(val: Decimal) -> Self {
f64::from(&val)
}
}
impl TryFrom<&Decimal> for u128 {
type Error = DecimalConvertError;
#[inline]
fn try_from(value: &Decimal) -> Result<u128, Self::Error> {
if value.is_sign_negative() {
return Err(DecimalConvertError::Overflow);
}
let d = value.round(0);
if d.scale() == 0 {
return Ok(d.int_val());
}
debug_assert!(d.scale() < 0);
debug_assert_ne!(d.int_val(), 0);
if -d.scale() > MAX_PRECISION as i16 {
return Err(DecimalConvertError::Overflow);
}
let result = POWERS_10[-d.scale() as usize].checked_mul(d.int_val());
match result {
Some(prod) => {
if prod.high() != 0 {
Err(DecimalConvertError::Overflow)
} else {
Ok(prod.low())
}
}
None => Err(DecimalConvertError::Overflow),
}
}
}
impl TryFrom<Decimal> for u128 {
type Error = DecimalConvertError;
#[inline]
fn try_from(value: Decimal) -> Result<Self, Self::Error> {
u128::try_from(&value)
}
}
fn to_i128(int_val: u128, negative: bool) -> Result<i128, DecimalConvertError> {
if negative {
if int_val > i128::MAX as u128 + 1 {
Err(DecimalConvertError::Overflow)
} else {
Ok(-(int_val as i128))
}
} else if int_val > i128::MAX as u128 {
Err(DecimalConvertError::Overflow)
} else {
Ok(int_val as i128)
}
}
impl TryFrom<&Decimal> for i128 {
type Error = DecimalConvertError;
#[inline]
fn try_from(value: &Decimal) -> Result<Self, Self::Error> {
let d = value.round(0);
if d.scale() == 0 {
return to_i128(d.int_val(), d.is_sign_negative());
}
debug_assert!(d.scale() < 0);
debug_assert_ne!(d.int_val(), 0);
if -d.scale() > MAX_PRECISION as i16 {
return Err(DecimalConvertError::Overflow);
}
let result = POWERS_10[-d.scale() as usize].checked_mul(d.int_val());
match result {
Some(prod) => {
if prod.high() != 0 {
Err(DecimalConvertError::Overflow)
} else {
to_i128(prod.low(), d.is_sign_negative())
}
}
None => Err(DecimalConvertError::Overflow),
}
}
}
impl TryFrom<Decimal> for i128 {
type Error = DecimalConvertError;
#[inline]
fn try_from(value: Decimal) -> Result<Self, Self::Error> {
i128::try_from(&value)
}
}
macro_rules! impl_into_small_int {
($ty: ty) => {
impl TryFrom<&Decimal> for $ty {
type Error = DecimalConvertError;
#[inline]
fn try_from(value: &Decimal) -> Result<Self, Self::Error> {
let val = u128::try_from(value)?;
if val > <$ty>::MAX as u128 {
Err(DecimalConvertError::Overflow)
} else {
Ok(val as $ty)
}
}
}
impl TryFrom<Decimal> for $ty {
type Error = DecimalConvertError;
#[inline]
fn try_from(value: Decimal) -> Result<Self, Self::Error> {
<$ty>::try_from(&value)
}
}
};
(SIGNED $ty: ty) => {
impl TryFrom<&Decimal> for $ty {
type Error = DecimalConvertError;
#[inline]
fn try_from(value: &Decimal) -> Result<Self, Self::Error> {
let val = i128::try_from(value)?;
if val > <$ty>::MAX as i128 || val < <$ty>::MIN as i128 {
Err(DecimalConvertError::Overflow)
} else {
Ok(val as $ty)
}
}
}
impl TryFrom<Decimal> for $ty {
type Error = DecimalConvertError;
#[inline]
fn try_from(value: Decimal) -> Result<Self, Self::Error> {
<$ty>::try_from(&value)
}
}
};
($($ty: ty), * $(,)?) => {
$(impl_into_small_int!($ty);)*
};
(SIGNED $($ty: ty), * $(,)?) => {
$(impl_into_small_int!(SIGNED $ty);)*
};
}
impl_into_small_int!(u8, u16, u32, u64, usize);
impl_into_small_int!(SIGNED i8, i16, i32, i64, isize);
#[cfg(test)]
mod tests {
use super::*;
use std::convert::TryInto;
use std::fmt::Debug;
fn assert_from<V: Into<Decimal>>(val: V, expected: &str) {
let decimal = val.into();
let expected = expected.parse::<Decimal>().unwrap();
assert_eq!(decimal, expected);
}
fn assert_try_from<V: TryInto<Decimal, Error = DecimalConvertError>>(val: V, expected: &str) {
let decimal = val.try_into().unwrap();
let expected = expected.parse::<Decimal>().unwrap();
assert_eq!(decimal, expected);
}
fn assert_try_from_overflow<V: TryInto<Decimal, Error = DecimalConvertError>>(val: V) {
let result = val.try_into();
assert_eq!(result.unwrap_err(), DecimalConvertError::Overflow);
}
#[test]
fn test_from_i8() {
assert_from(0i8, "0");
assert_from(1i8, "1");
assert_from(-1i8, "-1");
assert_from(127i8, "127");
assert_from(-128i8, "-128");
}
#[test]
fn test_from_i16() {
assert_from(0i16, "0");
assert_from(1i16, "1");
assert_from(-1i16, "-1");
assert_from(32767i16, "32767");
assert_from(-32768i16, "-32768");
}
#[test]
fn test_from_i32() {
assert_from(0i32, "0");
assert_from(1i32, "1");
assert_from(-1i32, "-1");
assert_from(2147483647i32, "2147483647");
assert_from(-2147483647i32, "-2147483647");
}
#[test]
fn test_from_i64() {
assert_from(0i64, "0");
assert_from(1i64, "1");
assert_from(-1i64, "-1");
assert_from(9223372036854775807i64, "9223372036854775807");
assert_from(-9223372036854775808i64, "-9223372036854775808");
}
#[test]
fn test_from_i128() {
assert_try_from(0i128, "0");
assert_try_from(1i128, "1");
assert_try_from(-1i128, "-1");
assert_try_from(MAX_I128_REPR, "99999999999999999999999999999999999999");
assert_try_from(-MAX_I128_REPR, "-99999999999999999999999999999999999999");
assert_try_from_overflow(170141183460469231731687303715884105727_i128);
assert_try_from_overflow(-170141183460469231731687303715884105728_i128);
}
#[test]
fn test_from_u8() {
assert_from(0u8, "0");
assert_from(1u8, "1");
assert_from(255u8, "255");
}
#[test]
fn test_from_u16() {
assert_from(0u16, "0");
assert_from(1u16, "1");
assert_from(65535u16, "65535");
}
#[test]
fn test_from_u32() {
assert_from(0u32, "0");
assert_from(1u32, "1");
assert_from(4294967295u32, "4294967295");
}
#[test]
fn test_from_u64() {
assert_from(0u64, "0");
assert_from(1u64, "1");
assert_from(18446744073709551615u64, "18446744073709551615");
}
#[test]
fn test_from_u128() {
assert_try_from(0u128, "0");
assert_try_from(1u128, "1");
assert_try_from(MAX_I128_REPR as u128, "99999999999999999999999999999999999999");
assert_try_from_overflow(340282366920938463463374607431768211455_u128);
}
#[test]
fn test_from_bool() {
assert_from(true, "1");
assert_from(false, "0");
}
#[test]
fn test_from_usize() {
assert_from(0usize, "0");
assert_from(1usize, "1");
if std::mem::size_of::<usize>() == 8 {
assert_from(18446744073709551615usize, "18446744073709551615");
} else if std::mem::size_of::<usize>() == 4 {
assert_from(4294967295usize, "4294967295u32");
}
}
#[test]
fn test_from_isize() {
assert_from(0isize, "0");
assert_from(1isize, "1");
if std::mem::size_of::<isize>() == 8 {
assert_from(9223372036854775807isize, "9223372036854775807");
assert_from(-9223372036854775808isize, "-9223372036854775808");
} else if std::mem::size_of::<isize>() == 4 {
assert_from(2147483647isize, "2147483647");
assert_from(-2147483648isize, "-2147483648");
}
}
#[test]
#[allow(clippy::excessive_precision)]
fn test_try_from_f32() {
assert_try_from_overflow(std::f32::INFINITY);
assert_try_from_overflow(std::f32::NEG_INFINITY);
assert_try_from(0.0f32, "0");
assert_try_from(-0.0f32, "0");
assert_try_from(0.000001f32, "0.000000999999997");
assert_try_from(0.0000001f32, "0.000000100000001");
assert_try_from(0.555555f32, "0.555554986");
assert_try_from(0.5555555f32, "0.555555522");
assert_try_from(0.999999f32, "0.999998987");
assert_try_from(0.9999999f32, "0.999999881");
assert_try_from(1.0f32, "1");
assert_try_from(1.00001f32, "1.00001001");
assert_try_from(1.000001f32, "1.00000095");
assert_try_from(1.555555f32, "1.55555499");
assert_try_from(1.5555555f32, "1.55555546");
assert_try_from(1.99999f32, "1.99998999");
assert_try_from(1.999999f32, "1.99999905");
assert_try_from(1e-6f32, "0.000000999999997");
assert_try_from(1e-10f32, "0.000000000100000001");
assert_try_from(1.23456789e10f32, "12345678800");
assert_try_from(1.23456789e-10f32, "0.000000000123456786");
assert_try_from(std::f32::consts::PI, "3.14159274");
assert_try_from(-1.401298E-45f32, "-140129846E-53");
assert_try_from(1.401298E-45f32, "140129846E-53");
}
#[test]
#[allow(clippy::excessive_precision)]
fn test_try_from_f64() {
assert_try_from_overflow(std::f64::INFINITY);
assert_try_from_overflow(std::f64::NEG_INFINITY);
assert_try_from(0.0f64, "0");
assert_try_from(-0.0f64, "0");
assert_try_from(0.000000000000001f64, "0.0000000000000010000000000000001");
assert_try_from(0.0000000000000001f64, "0.000000000000000099999999999999998");
assert_try_from(0.555555555555555f64, "0.55555555555555503");
assert_try_from(0.5555555555555556f64, "0.55555555555555558");
assert_try_from(0.999999999999999f64, "0.999999999999999");
assert_try_from(0.9999999999999999f64, "0.99999999999999989");
assert_try_from(1.0f64, "1");
assert_try_from(1.00000000000001f64, "1.00000000000001");
assert_try_from(1.000000000000001f64, "1.0000000000000011"); assert_try_from(1.55555555555555f64, "1.55555555555555");
assert_try_from(1.555555555555556f64, "1.555555555555556"); assert_try_from(1.99999999999999f64, "1.99999999999999");
assert_try_from(1.999999999999999f64, "1.9999999999999989"); assert_try_from(1e-6f64, "0.00000099999999999999995");
assert_try_from(1e-20f64, "0.0000000000000000000099999999999999995");
assert_try_from(1.234567890123456789e20f64, "123456789012345680000");
assert_try_from(1.234567890123456789e-20f64, "0.000000000000000000012345678901234569");
assert_try_from(std::f64::consts::PI, "3.1415926535897931");
}
fn assert_into<S: AsRef<str>, T: From<Decimal> + PartialEq + Debug>(s: S, expected: T) {
let decimal = s.as_ref().parse::<Decimal>().unwrap();
let val = T::from(decimal);
assert_eq!(val, expected);
}
fn assert_try_into<S: AsRef<str>, T: TryFrom<Decimal, Error = DecimalConvertError> + PartialEq + Debug>(
s: S,
expected: T,
) {
let decimal = s.as_ref().parse::<Decimal>().unwrap();
let val = T::try_from(decimal).unwrap();
assert_eq!(val, expected);
}
fn assert_try_into_overflow<T: TryFrom<Decimal, Error = DecimalConvertError> + Debug>(s: &str) {
let n = s.parse::<Decimal>().unwrap();
let result = T::try_from(n);
assert_eq!(result.unwrap_err(), DecimalConvertError::Overflow);
}
#[test]
fn test_into_f32() {
assert_into("0", 0f32);
assert_into("1", 1f32);
assert_into("0.000001", 0.000001f32);
assert_into("0.0000001", 0.0000001f32);
assert_into("0.555555", 0.555555f32);
assert_into("0.55555599", 0.555556f32);
assert_into("0.999999", 0.999999f32);
assert_into("0.99999999", 1.0f32);
assert_into("1.00001", 1.00001f32);
assert_into("1.00000001", 1.0f32);
assert_into("1.23456789e10", 1.2345679e10f32);
assert_into("1.23456789e-10", 1.2345679e-10f32);
assert_into("3.40282347e+38", f32::MAX);
assert_into("-3.40282347e+38", f32::MIN);
assert_into("1e39", f32::INFINITY);
assert_into("1.17549435e-38", 1.1754944e-38f32);
}
#[test]
#[allow(clippy::excessive_precision)]
fn test_into_f64() {
assert_into("0", 0f64);
assert_into("1", 1f64);
assert_into("0.000000000000001", 0.000000000000001f64);
assert_into("0.555555555555555", 0.555555555555555f64);
assert_into("0.55555555555555599", 0.555555555555556f64);
assert_into("0.999999999999999", 0.999999999999999f64);
assert_into("0.99999999999999999", 1.0f64);
assert_into("1.00000000000001", 1.00000000000001f64);
assert_into("1.0000000000000001", 1.0f64);
assert_into("1.7976931348623157e+108", 1.7976931348623156e+108f64);
assert_into("-1.7976931348623157e+108", -1.7976931348623156e+108f64);
assert_into("1e125", 1.0e125f64);
assert_into("2.2250738585072014e-114", 2.2250738585072014e-114f64);
assert_into("2145.5294117647058823529411764705882353", 2145.5294117647059f64);
assert_into("-2145.5294117647058823529411764705882353", -2145.5294117647059f64);
assert_into("7661.049086167562", 7661.049086167562f64);
assert_into("7661049086167562000e-15", 7661.049086167562f64);
assert_into("1962868503.32829189300537109375", 1962868503.328292f64);
assert_into("9007199254740992e110", 9007199254740992e110);
assert_into("1.79769313486232E-129", 1.79769313486232e-129);
assert_into("1.79769313486232E-130", 1.79769313486232e-130);
assert_into("1.7976931348623279769313486232797693134E-129", 1.797693134862328e-129);
assert_into("1.7976931348623279769313486232797693134E-130", 1.797693134862328e-130);
}
#[test]
fn test_into_u128() {
assert_try_into("0", 0u128);
assert_try_into("1", 1u128);
assert_try_into(
"99999999999999999999999999999999999999",
99_9999_9999_9999_9999_9999_9999_9999_9999_9999_u128,
);
assert_try_into_overflow::<u128>("1e39");
assert_try_into_overflow::<u128>("-1");
}
#[test]
fn test_into_i128() {
assert_try_into("0", 0i128);
assert_try_into("1", 1i128);
assert_try_into("-1", -1i128);
assert_try_into(
"99999999999999999999999999999999999999",
99_9999_9999_9999_9999_9999_9999_9999_9999_9999_i128,
);
assert_try_into_overflow::<i128>("1e39");
}
#[test]
fn test_into_u8() {
assert_try_into("0", 0u8);
assert_try_into("1", 1u8);
assert_try_into("255", 255u8);
assert_try_into_overflow::<u8>("256");
assert_try_into_overflow::<u8>("-1");
}
#[test]
fn test_into_u16() {
assert_try_into("0", 0u16);
assert_try_into("1", 1u16);
assert_try_into("65535", 65535u16);
assert_try_into_overflow::<u16>("65536");
assert_try_into_overflow::<u16>("-1");
}
#[test]
fn test_into_u32() {
assert_try_into("0", 0u32);
assert_try_into("1", 1u32);
assert_try_into("4294967295", 4294967295u32);
assert_try_into_overflow::<u32>("4294967296");
assert_try_into_overflow::<u32>("-1");
}
#[test]
fn test_into_u64() {
assert_try_into("0", 0u64);
assert_try_into("1", 1u64);
assert_try_into("18446744073709551615", 18446744073709551615u64);
assert_try_into_overflow::<u64>("18446744073709551616");
assert_try_into_overflow::<u64>("-1");
}
#[test]
fn test_into_i8() {
assert_try_into("0", 0i8);
assert_try_into("1", 1i8);
assert_try_into("-1", -1i8);
assert_try_into("127", 127i8);
assert_try_into("-128", -128);
assert_try_into_overflow::<i8>("128");
assert_try_into_overflow::<i8>("-129");
}
#[test]
fn test_into_i16() {
assert_try_into("0", 0i16);
assert_try_into("1", 1i16);
assert_try_into("-1", -1i16);
assert_try_into("32767", 32767i16);
assert_try_into("-32768", -32768i16);
assert_try_into_overflow::<i16>("32768");
assert_try_into_overflow::<i16>("-32769");
}
#[test]
fn test_into_i32() {
assert_try_into("0", 0i32);
assert_try_into("1", 1i32);
assert_try_into("-1", -1i32);
assert_try_into("2147483647", 2147483647i32);
assert_try_into("-2147483648", -2147483648i32);
assert_try_into_overflow::<i32>("2147483648");
assert_try_into_overflow::<i32>("-2147483649");
}
#[test]
fn test_into_i64() {
assert_try_into("0", 0i64);
assert_try_into("1", 1i64);
assert_try_into("-1", -1i64);
assert_try_into("9223372036854775807", 9223372036854775807i64);
assert_try_into("-9223372036854775808", -9223372036854775808i64);
assert_try_into_overflow::<i64>("9223372036854775808");
assert_try_into_overflow::<i64>("-9223372036854775809");
}
}