aligners 0.0.3

Utilities for alignment guarantees for data.
Documentation
# `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)
[![docs.rs](https://img.shields.io/docsrs/aligners?logo=docs.rs)](https://docs.rs/aligners)
[![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/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)

[![Crates.io](https://img.shields.io/crates/l/aligners)](https://choosealicense.com/licenses/mit/)
[![Lines of code](https://img.shields.io/tokei/lines/github/v0ldek/aligners?label=LoC&logo=rust)](https://github.com/V0ldek/aligners/tree/main/src)

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<alignment::Page> = bytes.into();
```

That's it. `AlignedBytes<A>` owns the bytes. By taking a reference you get `&AlignedSlice<A>`, 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`:
<!--cspell: disable -->
```plain
aligners v0.0.1
├── cfg-if v1.0.0
├── lazy_static v1.4.0
└── page_size v0.4.2
    └── libc v0.2.125
```
<!--cspell: enable -->
### Justification

- `cfg-if` &ndash; 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` &ndash; used to lazily validate and cache the page size.
- `page_size` &ndash; used to get the page size for `alignment::Page`.

#### Dev

- `cargo-hack` &ndash; used for more robust testing by compiling and running the code for the feature powerset.

## `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
```