Skip to main content

module_lattice/
truncate.rs

1/// Safely truncate an unsigned integer value to shorter representation
2pub trait Truncate<T> {
3    /// Truncate value to the width of `Self`.
4    fn truncate(x: T) -> Self;
5}
6
7macro_rules! define_truncate {
8    ($from:ident, $to:ident) => {
9        impl Truncate<$from> for $to {
10            // Truncation should always function as intended here:
11            // - we ensure `$to` is small enough to infallibly convert to `$from` via the
12            //   `$from::from($to::MAX)` conversion, which will fail if not widening.
13            // - we are deliberately masking to the smaller size, i.e. truncation is intentional
14            //   (though that's not enough for `clippy` for some reason). Arguably the truncation
15            //   of the `as` cast is sufficient, but this makes it explicit
16            #[allow(clippy::cast_possible_truncation)]
17            fn truncate(x: $from) -> $to {
18                (x & $from::from($to::MAX)) as $to
19            }
20        }
21    };
22}
23
24define_truncate!(u32, u16);
25define_truncate!(u64, u16);
26define_truncate!(u64, u32);
27define_truncate!(u128, u8);
28define_truncate!(u128, u16);
29define_truncate!(u128, u32);
30define_truncate!(usize, u8);
31define_truncate!(usize, u16);