register_bits/
lib.rs

1//! A crate to perform register-bit manipulation which is verified at compile time
2//!
3//! This crate provides many inlined procedures for performing bit manipulations including taking a
4//! selection of bits, concatinating bits and forming new bitstring. All these manipulations are
5//! checked at compile time to ensure reliability at runtime at the cost of compilation duration.
6//!
7//! There are 4 different register types.
8//! - [A 8 bit register][reg8] which can be enabled with the `8bit` feature
9//! - [A 16 bit register][reg16] which can be enabled with the `16bit` feature
10//! - [A 32 bit register][reg32] which can be enabled with the `32bit` feature (included by default)
11//! - [A 64 bit register][reg64] which can be enabled with the `64bit` feature
12//!
13//! All the register variants can be included using the `all-regs` feature.
14//!
15//! # Usage
16
17//! To utilize most of the functionality a set of traits need to used. To utilize all the useful
18//! traites it is recommended to use the prelude.
19//!
20//! ## Basic Usage
21//!
22//! ```
23//! use register_bits::prelude::*;
24//!
25//! // Forms a Reg32Bits<32>
26//! let value = Reg32Bits::new(0x1234_5678);
27//!
28//! // Take substrings from value
29//! let low_12bits: Reg32Bits<12> = value.take_low(); // 0x678
30//! let high_12bits: Reg32Bits<12> = value.take_high(); // 0x123
31//!
32//! // Type of Reg32Bits<24> is automatically inferred
33//! let concatination = high_12bits.concat(low_12bits); // 0x123_678
34//!
35//! assert_eq!(high_12bits.concat(low_12bits), 0x123_678); 
36//! ```
37//!
38//! ## Casting
39//!
40//! ```
41//! use register_bits::prelude::*;
42//!
43//! // Forms a Reg32Bits<32>
44//! let value = Reg32Bits::new(0x1234_5678);
45//!
46//! let low_12bits: Reg32Bits<12> = value.take_low(); // 0x678
47//!
48//! // We can fetch the inner value
49//! let uint_value = u32::from(low_12bits);
50//! assert_eq!(uint_value, 0x678);
51//! 
52//! // Most of the operations you can do from within the struct however
53//! assert_eq!(low_12bits, 0x678);
54//! assert_eq!(low_12bits + 1u32, 0x679);
55//! assert_eq!(low_12bits - 1u32, 0x677);
56//! assert_eq!(low_12bits % 2u32, 0);
57//! assert_eq!(low_12bits >> 8u32, 0x6);
58//!
59//! // You can also add bits
60//! let bigger: Reg32Bits<16> = low_12bits.zero_extend(); // 0x0678
61//! let sign_extended: Reg32Bits<16> = low_12bits.sign_extend(); // 0x0678
62//! let padded: Reg32Bits<16> = low_12bits.zero_pad(); // 0x6780
63//! ```
64//!
65//! ## Individual bit manipulations
66//!
67//! ```
68//! use register_bits::prelude::*;
69//!
70//! // Forms a Reg32Bits<32>
71//! let value = Reg32Bits::new(0b1011_1000);
72//!
73//! let low_byte: Reg32Bits<8> = value.take_low(); // 0b1011_1000
74//!
75//! // We can get the value of individual bits
76//! let bits = low_byte.bits();
77//!
78//! // This is perfect for pattern matching
79//! assert_eq!(bits, [1, 0, 1, 1, 1, 0, 0, 0]);
80//! 
81//! // We can also get a bit from a runtime variable
82//! assert_eq!(low_byte.get(3).unwrap(), 1u8);
83//! ```
84//!
85//! # No-Std
86//!
87//! The `no-std` ensures that the environment does not utilize the standard library.
88//!
89//! # Development
90//!
91//! The `reg8.rs`, `reg16.rs`, `reg32.rs` and `reg64.rs` are automatically generated from the
92//! `reg_reference.rs` file. This is done with the `generate_impl_rs.py` script.
93
94#![cfg_attr(feature = "no-std", no_std)]
95
96pub mod prelude;
97
98#[cfg(feature = "8bit")]
99pub mod reg8;
100#[cfg(feature = "16bit")]
101pub mod reg16;
102#[cfg(feature = "32bit")]
103pub mod reg32;
104#[cfg(feature = "64bit")]
105pub mod reg64;
106
107#[cfg(test)]
108mod reg_reference;