MathUtils 1.0.1

A high-fidelity Rust mirror of the JavaScript (ECMAScript) Math built-in object.
Documentation
//! Traits and conversions mirroring JavaScript's `ToUint32` and `ToInt32` operations.

/// Converts numeric values to a 32-bit unsigned integer according to ECMAScript `ToUint32` (7.1.6).
///
/// In JavaScript, passing non-finite values (like `NaN` or `Infinity`) yields `0`, and the
/// integer part is wrapped modulo $2^{32}$.
pub trait ToJsUint32 {
    /// Converts `self` to `u32` following ECMAScript `ToUint32` semantics.
    fn to_js_uint32(self) -> u32;
}

/// Converts numeric values to a 32-bit signed integer according to ECMAScript `ToInt32` (7.1.5).
pub trait ToJsInt32 {
    /// Converts `self` to `i32` following ECMAScript `ToInt32` semantics.
    fn to_js_int32(self) -> i32;
}

impl ToJsUint32 for f64 {
    #[inline]
    fn to_js_uint32(self) -> u32 {
        if !self.is_finite() || self == 0.0 {
            return 0;
        }
        let int = self.trunc();
        let rem = int.rem_euclid(4294967296.0);
        rem as u64 as u32
    }
}

impl ToJsUint32 for f32 {
    #[inline]
    fn to_js_uint32(self) -> u32 {
        (self as f64).to_js_uint32()
    }
}

macro_rules! impl_to_js_uint32_for_int {
    ($($t:ty),*) => {
        $(
            impl ToJsUint32 for $t {
                #[inline]
                fn to_js_uint32(self) -> u32 {
                    self as u32
                }
            }
        )*
    };
}

impl_to_js_uint32_for_int!(u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);

impl<T: ToJsUint32> ToJsInt32 for T {
    #[inline]
    fn to_js_int32(self) -> i32 {
        self.to_js_uint32() as i32
    }
}