I did some experimenting in this area and wrote the az crate, which uses traits.
- You can write
i.az::<O>()
orcast::<I, O>(i)
instead ofi as O
, with overflow panicking withdebug_assertions
or wrapping otherwise. - There are other traits/casts for checked, saturating, wrapping and overflowing conversions, e.g.
i.checked_as::<O>()
. - For floating-point to integer conversions I chose truncation by default, but rounding is supported via a
Round
wrapper, so thatassert_eq!(0.6f32.az::<i32>(), 0); assert_eq!(Round(0.6f32).az::<i32>(), 1); // Ties round to even. assert_eq!(Round(0.5f32).az::<i32>(), 0); assert_eq!(Round(1.5f32).az::<i32>(), 2);
- I also wrote conversions into e.g
Wrapping<i32>
, which does wrapping. - For floating-point to integer conversions I used bitwise manipulation instead of intrinsic conversions as it wasn't clear what the guarantees where; this is probably much slower but every behavior is defined. And I was more interested in the API at this point.