fray 0.1.2

A type-safe and ergonomic Rust library for working with bitfields.
Documentation
use crate::BitFieldImpl;

/// Describes a type that can be stored in a [`BitField`](crate::BitField) via a [`Field`](crate::Field).
///
/// Provides the size of the type in bits and the corresponding storage type (BitsType)
/// used to convert the value to and from raw bits.
pub trait FieldType {
    /// The number of bits required to represent this value.
    const SIZE: usize;
    /// The raw type used to store this value in the underlying container.
    type BitsType;
}

/// Describe a single **field** within a [`BitField`](crate::BitField).
///
/// Each field of a [`BitField`](crate::BitField) struct implements `Field` automatically
/// via the `bitfield` macro. This trait is **not meant to be implemented manually**.
///
/// The type parameter `T` is the bitfield struct that this field belongs to,
/// this help ensuring that fields cannot be used on the wrong struct.
///
/// # Usage
///
/// End-users generally do not interact with `Field` directly.
/// Instead, use the convenience methods on the parent [`BitField`](crate::BitField) struct,
/// such as [`get`](crate::BitField::get) and [`set`](crate::BitField::set).
pub trait Field<T: BitFieldImpl> {
    /// The field's type, which must implement [`FieldType`].
    type Type: FieldType;
    /// The raw storage type into which `Type` is converted for storage,
    /// and from which it is converted back when retrieving.
    type BitsType;

    /// The bit offset where this field starts within the bitfield.
    const OFFSET: usize;
    /// The number of bits used by this field. Defaults to
    /// `<Self::Type>::SIZE`.
    const SIZE: usize = Self::Type::SIZE;
}

macro_rules! impl_field_type {
    ($ty:ty, $size:expr, $bitty:ty) => {
        impl FieldType for $ty {
            const SIZE: usize = $size;
            type BitsType = $bitty;
        }
    };
}

impl_field_type!(u32, 32, u32);
impl_field_type!(u16, 16, u16);
impl_field_type!(u8, 8, u8);
impl_field_type!(bool, 1, bool);
impl_field_type!((), 0, ());