pas-rs
pas (\pa\), meaning "step" in French, is a crate for slicing stuff, especially strided data.
pas allows you to:
- Get a slice with a custom stride
- Slice only a part of a struct
⚠️ This crate relies on casting between different data types ⚠️
- This operation is endian dependant
- No mechanism to encode/decode to/from big endian is provided
Examples
Macros
With Type Inference
Using slice_attr! to slice in a struct and automatically infer the type:
use ;
Without Type Inference
It can be useful to slice at a struct attribute, but with a smaller type:
let x_positions: = slice!;
println!; // [1.0, 1.0]
let y_positions: = slice!;
println!; // [0.5, 1.0]
let z_positions: = slice!;
println!; // [1.0, 0.5]
Slice and SliceMut
When slicing an array whose type information is known only at runtime, you can use Slice/SliceMut:
let uv_byte_offset = + ;
// Slice starting at the byte offset `32`, with a stride of 1 element.
let uvs: = new;
println!; // [[0.0, 1.0]]
Custom Stride
It's possible to use a custom stride, in elements count:
use ;
let data: = ;
// Using the macro, the stride appears first
let slice = slice_attr!;
println!; // [0, 2, 4]
// Specified as the last argument when using `Slice`/`SliceMut`
let slice: = strided;
println!; // [0, 3]
The stride must always be at least the size of the attribute. This example will panic:
use ;
let data: = ;
// Default stride is `std::mem::size_of::<u32>()` here, attribute
// size is `std::mem::size_of::<[u32; 3]>()`.
let _: = new;
Safety
While this crate makes use of unsafe and transmute, it's (mostly) safe
to use and comes with runtime checks preventing you to run into undefined behaviors:
- Ensure that reads are aligned
- Check size of read compared to stride
This crate requires your types to implement the Pod trait from the bytemuck crate, improving safety with alignment rules, and illegal bit patterns.