modular_bitfield/
lib.rs

1#![doc = include_str!("../docs/index.md")]
2#![no_std]
3#![forbid(unsafe_code)]
4#![warn(clippy::pedantic, missing_docs, rust_2018_idioms)]
5
6pub mod error;
7#[doc(hidden)]
8pub mod private;
9
10use self::error::{InvalidBitPattern, OutOfBounds};
11
12#[doc = include_str!("../docs/bitfield.md")]
13pub use modular_bitfield_impl::bitfield;
14
15#[doc = include_str!("../docs/bitfield_specifier.md")]
16pub use modular_bitfield_impl::Specifier;
17
18/// The prelude: `use modular_bitfield::prelude::*;`
19pub mod prelude {
20    pub use super::{bitfield, specifiers::*, Specifier};
21}
22
23/// The `Specifier` trait describes a sequence of bits stored in an integer
24/// primitive (the [`Bytes`](Self::Bytes) type) and how to convert them to/from
25/// a more convenient higher-level interface type (the [`InOut`](Self::InOut)
26/// type).
27///
28/// For example:
29///
30/// * The specifier for `bool` converts between a `u8` with a 1 or 0 bit in
31///   the lowest bit position and a native `bool`.
32/// * The specifier for a unit enum with variants `{0, 1, 14}` converts
33///   between a `u16` matching those variants and the enum type.
34/// * The specifier for a 20-bit struct converts between a `u32` and the
35///   struct type.
36///
37/// All types used in a `#[bitfield]` struct must implement this trait, and it
38/// should usually only be implemented with
39/// [`#[derive(Specifier)]`](macro@crate::Specifier).
40pub trait Specifier {
41    /// The number of bits used by the `Specifier`.
42    const BITS: usize;
43
44    /// The storage type. This is typically the smallest integer primitive that
45    /// can store all possible values of the [`InOut`](Self::InOut) type.
46    type Bytes;
47
48    /// The interface type. This type is used by getters and setters. For
49    /// integers, this is the same as the [`Bytes`](Self::Bytes) type; for other
50    /// types with more logical representations, like an enum or struct, this is
51    /// the enum or struct.
52    type InOut;
53
54    /// Converts an interface type into its storage type.
55    ///
56    /// # Errors
57    ///
58    /// If the input value is out of bounds, an error will be returned. For
59    /// example, the value `b100_u8` cannot be converted with `B2` because it is
60    /// three bits wide.
61    fn into_bytes(input: Self::InOut) -> Result<Self::Bytes, OutOfBounds>;
62
63    /// Converts a storage type into its interface type.
64    ///
65    /// # Errors
66    ///
67    /// If the given bit pattern is invalid for the interface type, an error
68    /// will be returned. For example, `3_u8` cannot be converted to an enum
69    /// which only has variants `{0, 1, 2}`.
70    fn from_bytes(bytes: Self::Bytes) -> Result<Self::InOut, InvalidBitPattern<Self::Bytes>>;
71}
72
73/// The default set of predefined specifiers.
74pub mod specifiers {
75    ::modular_bitfield_impl::define_specifiers!();
76}