# `aligners` – strongly typed memory alignment guarantees [![Rust](https://github.com/V0ldek/aligners/actions/workflows/rust.yml/badge.svg)](https://github.com/V0ldek/aligners/actions/workflows/rust.yml) [![Miri](https://github.com/V0ldek/aligners/actions/workflows/miri.yml/badge.svg)](https://github.com/V0ldek/aligners/actions/workflows/miri.yml) [![docs.rs](https://img.shields.io/docsrs/aligners?logo=docs.rs)](https://docs.rs/aligners) [![Crates.io](https://img.shields.io/crates/v/aligners?logo=docs.rs)](https://crates.io/crates/aligners) [![GitHub Release Date](https://img.shields.io/github/release-date/v0ldek/aligners)](https://github.com/V0ldek/aligners/releases) [![GitHub last commit](https://img.shields.io/github/last-commit/v0ldek/aligners?logo=github)](https://github.com/V0ldek/aligners/commits/main) [![Crates.io](https://img.shields.io/crates/l/aligners)](https://choosealicense.com/licenses/mit/) Some bytes just need to be aligned. Want to process bytes in batches of 8 by interpreting them as `u64`? They must be 8-byte aligned. Want to run SIMD operations on your bytes? You need to use special unaligned instructions and risk performance, or align them with target's requirements. Maybe your high-performance algorithm requires page alignment? Validating that something is aligned is hard. `aligners` solves this problem by introducing strongly typed alignment types. To have your bytes aligned to a page boundary on the target architecture, all you need to do is: ```rust use aligners::{alignment, AlignedBytes}; let bytes: [u8; 8] = [ 1, 2, 3, 4, 5, 6, 7, 8 ]; let aligned: AlignedBytes = bytes.into(); ``` That's it. `AlignedBytes` owns the bytes. By taking a reference you get `&AlignedSlice`, which is basically the same as `&[u8]`, only that its alignment is guaranteed by the type. ## Status This crate is under active development and the API is unstable. It contains the MVP of being able to align your bytes to page or SIMD-block boundary and iterate over aligned blocks. The crate is continuously built and tested on a number of architectures. We also use [Miri](https://github.com/rust-lang/miri) on multiple target triples to test for hard-to-find bugs. ## Unsafety This crate needs to use `unsafe` code due to the low-level pointer-twiddling nature of the domain. Two places where `unsafe` is required are: - creating the `AlignedBytes`, as it requires explicitly working with the allocator to get properly aligned bytes; - converting between `AlignedSlice` and regular byte slices, which relies on `repr(transparent)` of the former to be `mem::transmute`-able into the latter. - working internally on `AlignedBlock` to maintain the type's invariants. Reviews via [cargo-crev](https://github.com/crev-dev/cargo-crev) are appreciated. ## Dependencies Dependencies graph generated by `cargo-deps`: ![ dependencies graph ](deps.png) Or as the output of `cargo tree`: ```plain aligners v0.0.1 ├── cfg-if v1.0.0 ├── lazy_static v1.4.0 └── page_size v0.4.2 └── libc v0.2.125 ``` ### Justification - `cfg-if` – used to configure conditional compilation in a more readable manner, especially determining SIMD block size. It's lightweight and contains no unsafe code. - `lazy_static` – used to lazily validate and cache the page size. - `page_size` – used to get the page size for `alignment::Page`. #### Dev - `cargo-hack` – used for more robust testing by compiling and running the code for the feature powerset. - `anyhow` – used in the `simd_alignment_test` to make error handling easy. ## `crev` It is recommended to always use [cargo-crev](https://github.com/crev-dev/cargo-crev) to verify the trustworthiness of each of your dependencies, including this one. Reviews are appreciated. To add me to your WoT trust my crev-proof repo: ```plain cargo crev trust id https://github.com/V0ldek/crev-proofs ```