Instantly share code, notes, and snippets.

Embed
What would you like to do?
Code shared from the Rust Playground
fn check_safe_transmute<T: Copy>(buf: &[u8]) {
if buf.len() < ::std::mem::size_of::<T>() {
panic!("Slice has insufficient capacity!");
}
let p = buf.as_ptr() as usize;
let align_of = ::std::mem::align_of::<T>();
if align_of > 0 && (p & (align_of - 1)) != 0 {
panic!("Slice has bad alignment!");
}
}
trait ViewExt {
fn view_as<T>(&self) -> &T where T: Copy;
fn view_mut<T>(&mut self) -> &mut T where T: Copy;
}
impl ViewExt for [u8] {
fn view_as<T>(&self) -> &T where T: Copy {
check_safe_transmute::<T>(self);
unsafe {
&*::std::mem::transmute::<*const u8, *const T>(self.as_ptr())
}
}
fn view_mut<T>(&mut self) -> &mut T where T: Copy {
check_safe_transmute::<T>(self);
unsafe {
&mut *::std::mem::transmute::<*mut u8, *mut T>(self.as_mut_ptr())
}
}
}
#[repr(packed)]
#[derive(Clone, Copy, Debug)]
struct Ipv4Addr {
addr: [u8; 4],
}
fn main() {
let mut buf = [0; 8];
buf[0] = 1;
{
let addr = buf.view_mut::<Ipv4Addr>();
assert!(addr.addr[0] == 1);
addr.addr[1] = 2;
println!("{:?}", addr);
}
assert!(buf[1] == 2);
println!("{:?}", buf);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment