easy-cast 0.6.0

Type conversions which are expected to succeed
Documentation
#![cfg(any(feature = "std", feature = "libm"))]

use easy_cast::{Error, traits::*};

#[test]
fn float_boundaries_for_small_integer_types() {
    assert_eq!(i8::try_conv_trunc(f32::from(i8::MIN)), Ok(i8::MIN));
    assert_eq!(i8::try_conv_trunc(f32::from(i8::MAX)), Ok(i8::MAX));
    assert_eq!(
        i8::try_conv_trunc(f32::from(i8::MIN) - 1.0),
        Err(Error::Range)
    );
    assert_eq!(
        i8::try_conv_trunc(f32::from(i8::MAX) + 1.0),
        Err(Error::Range)
    );

    assert_eq!(u8::try_conv_nearest(255.0f32), Ok(u8::MAX));
    assert_eq!(u8::try_conv_nearest(256.0f32), Err(Error::Range));

    assert_eq!(i16::try_conv_floor(f64::from(i16::MIN)), Ok(i16::MIN));
    assert_eq!(i16::try_conv_ceil(f64::from(i16::MAX)), Ok(i16::MAX));
    assert_eq!(
        i16::try_conv_floor(f64::from(i16::MIN) - 1.0),
        Err(Error::Range)
    );
    assert_eq!(
        i16::try_conv_ceil(f64::from(i16::MAX) + 1.0),
        Err(Error::Range)
    );

    assert_eq!(u32::try_conv_trunc(f64::from(u32::MAX)), Ok(u32::MAX));
    assert_eq!(
        u32::try_conv_trunc(f64::from(u32::MAX) + 1.0),
        Err(Error::Range)
    );
}

#[test]
fn nan_and_infinity_are_range_errors_for_all_modes() {
    for value in [f32::NAN, f32::INFINITY, f32::NEG_INFINITY] {
        assert_eq!(i8::try_conv_trunc(value), Err(Error::Range));
        assert_eq!(i8::try_conv_nearest(value), Err(Error::Range));
        assert_eq!(i8::try_conv_floor(value), Err(Error::Range));
        assert_eq!(i8::try_conv_ceil(value), Err(Error::Range));

        assert_eq!(u128::try_conv_trunc(value), Err(Error::Range));
        assert_eq!(u128::try_conv_nearest(value), Err(Error::Range));
        assert_eq!(u128::try_conv_floor(value), Err(Error::Range));
        assert_eq!(u128::try_conv_ceil(value), Err(Error::Range));
    }

    for value in [f64::NAN, f64::INFINITY, f64::NEG_INFINITY] {
        assert_eq!(i16::try_conv_trunc(value), Err(Error::Range));
        assert_eq!(i16::try_conv_nearest(value), Err(Error::Range));
        assert_eq!(i16::try_conv_floor(value), Err(Error::Range));
        assert_eq!(i16::try_conv_ceil(value), Err(Error::Range));
    }
}

#[test]
fn f32_to_u128_special_case() {
    let max = 0xFFFFFF00_00000000_00000000_00000000u128;
    assert_eq!(u128::try_conv_trunc(f32::MAX), Ok(max));
    assert_eq!(u128::try_conv_nearest(f32::MAX), Ok(max));
    assert_eq!(u128::try_conv_floor(f32::MAX), Ok(max));
    assert_eq!(u128::try_conv_ceil(f32::MAX), Ok(max));
    assert_eq!(u128::try_conv_trunc(0.0f32), Ok(0u128));
    assert_eq!(u128::try_conv_trunc(-1.0f32), Err(Error::Range));
    assert_eq!(u128::try_conv_trunc(f32::INFINITY), Err(Error::Range));
}

#[test]
#[should_panic(expected = "cast x: f32 to i16 (trunc): range error for x = 32768")]
fn float_conv_trunc_panics_with_expected_message() {
    i16::conv_trunc(32768.0f32);
}

#[test]
#[should_panic(expected = "cast x: f64 to u8 (ceil): range error for x = -1.1")]
fn float_conv_ceil_panics_with_expected_message() {
    u8::conv_ceil(-1.1f64);
}