Lokathor / bytemuck

A crate for mucking around with piles of bytes
https://docs.rs/bytemuck
Apache License 2.0
697 stars 77 forks source link

conversion from `&[u8]` to `&[T]`? #229

Closed cmyr closed 6 months ago

cmyr commented 6 months ago

I assume I'm just missing this, but I don't see a conversion function for reinterpreting a byte slice as a slice of some type T. Assuming that other invariants are upheld and that slice.len() is divisible by size_of::<T>() then I think this should be fine. Am I overlooking anything?

zachs18 commented 6 months ago

This is cast_slice. Note that it will (correctly) fail if the slice's address is not aligned to std::mem::align_of::<T>(), since a &[T] must be aligned to the alignment of T.

Lokathor commented 6 months ago

Yep.

Best practice is to start with the most aligned type you want a slice of and then cast_slice to a less aligned type (if any).

// using u64 as an example type:
let mut buf: Vec<u64> = vec![0_u64; 32];
let byte_buf: &mut [u8] = cast_slice_mut(&mut buf);

copy_u64_data_to_byte_buffer_somehow(byte_buf);

// now `buf` has the updated u64 values.
cmyr commented 6 months ago

ah okay I was confused thinking that cast_slice required a 1:1 correspondence between A and B. Thanks!

Lokathor commented 6 months ago

The output slice will have an adjusted size when the start and end types differ in size. If an exact output size doesn't work it will panic. If you want to avoid the panic, the try_ versions can do that.

For example, a slice of two 4-byte entries (8 bytes) cast to a type that's 6 bytes big would have 2 "slop" bytes, and that would error/panic.