#transmute #convert #cast #zero-copy

convute

Conversion between types with overlapping valid bit patterns and arrays, vecs and slices of those values

3 unstable releases

0.2.0 Mar 12, 2019
0.1.1 Mar 12, 2019
0.1.0 Mar 12, 2019

#2853 in Rust patterns

Apache-2.0

20KB
504 lines

crates.io docs.rs

Goal

Allow conversion between types that have overlapping valid values.

Method

We achieve this through the unsafe marker traits convute::marker::Transmute and convute::marker::TryTransmute which enable conversions between values, references, arrays, vecs and slices.


lib.rs:

The purpose of convute is to let you convert between types of the same size with overlapping valid bit patterns. To do so, you must implement the unsafe convute::marker::Transmute or convute::marker::TryTransmute traits on your types. The great thing about these markers is that we can derive conversions between arrays, vecs and slices of those types.

// Import the traits which implement the conversions.
use convute::convert::*;

// This type represents a value in the range 0..9.
struct Lt9(u8);

impl Lt9 {
    #[inline]
    fn new(val: u8) -> Option<Self> {
        if val < 9 { Some(Lt9(val)) } else { None }
    }
}

// Let convute know every Lt9 is a valid u8.
unsafe impl convute::marker::Transmute<u8> for Lt9 {}

// Let convute know some u8 are valid Lt9.
unsafe impl convute::marker::TryTransmute<Lt9> for u8 {
    #[inline]
    fn can_transmute(&self) -> bool {
        Lt9::new(*self).is_some()
    }
}

fn main() {
    let numbers = [1, 6, 10, 5];
    let all_lt9: Result<[Lt9; 4], [u8; 4]> = numbers.try_transmute_each();
    // Because of the 10, the conversion will fail.
    assert!(all_lt9.is_err());
}

Check out the tests in convert.rs for more examples.

No runtime deps