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}