fray 0.1.2

A type-safe and ergonomic Rust library for working with bitfields.
Documentation
# fray

A type-safe and ergonomic Rust library for working with bitfields.

`fray` lets you define structured bitfields using the `#[bitfield]` attribute macro, and interact with their fields through strongly-typed getters and setters. This means you can get and set values without manually shifting or masking bits, while still working with packed data in a convenient, high-level way.

[![Crates.io](https://img.shields.io/crates/v/fray.svg)](https://crates.io/crates/fray)
[![Documentation](https://docs.rs/fray/badge.svg)](https://docs.rs/fray)
[![CI](https://github.com/legleo/fray/actions/workflows/ci.yml/badge.svg)](https://github.com/legleo/fray/actions/workflows/ci.yml)

### Features

- Define bitfield structs with an attribute macro, using syntax identical to classic Rust structs.
- Fully compatible with `no_std`, requiring no heap allocations.
- Manipulate fields type-safely, without manual shifting or masking.
- Support both primitive and custom field types.
- Ensures at compile time that fields fit their containers.
- Choose different storage backends for bitfields without losing others features.

### Documentation

[Crate documentation with examples](https://docs.rs/fray).

### Example

```rust
use fray::{BitField, FieldType, bitfield};

#[bitfield(repr(u8), derives(Clone, Copy), impls(debug), bitorder(msb0))]
pub struct LinkControl {
    version: Version,
    encrypted: bool,
    ack: bool,
    #[bits(3)]
    sequence: u8,
    #[bits(1)]
    _reserved: (),
}

fn main() {
    let mut link_control = LinkControl::new();
    link_control
        .with::<version>(Version::V3)
        .with::<sequence>(5)
        .with::<ack>(true);

    assert!(link_control.get::<ack>());
    assert_eq!(link_control.try_get::<version>(), Ok(Version::V3));
    assert_eq!(link_control.get::<sequence>(), 5);

    let copy = link_control;

    link_control.set::<ack>(false);
    link_control.set::<encrypted>(true);
    assert!(!link_control.get::<ack>());
    assert!(link_control.get::<encrypted>());

    let copy_fmt = format!("{:?}", copy);
    let expected =
        "LinkControl { version: V3, encrypted: false, ack: true, sequence: 5 }";
    assert_eq!(expected, copy_fmt);
    assert_eq!(copy.into_inner(), 0b11_0_1_101_0);
}

#[repr(u8)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum Version {
    V0 = 0,
    V1 = 1,
    V2 = 2,
    V3 = 3,
}

impl FieldType for Version {
    const SIZE: usize = 2;
    type BitsType = u8;
}

impl From<Version> for u8 {
    fn from(value: Version) -> Self {
        value as u8
    }
}

impl TryFrom<u8> for Version {
    type Error = u8;

    fn try_from(value: u8) -> Result<Self, Self::Error> {
        Ok(match value {
            0 => Self::V0,
            1 => Self::V1,
            2 => Self::V2,
            3 => Self::V3,
            value => return Err(value),
        })
    }
}
```

### License

This project is licensed under the [**MIT License**](https://opensource.org/licenses/MIT).