mju_bits/lib.rs
1/*
2mju-bits - typed bitfield manipulation
3
4Copyright 2019-2020 David Kern <david@mju.io>
5
6Licensed under the Apache License, Version 2.0 (the "License");
7you may not use this file except in compliance with the License.
8You may obtain a copy of the License at
9
10 http://www.apache.org/licenses/LICENSE-2.0
11
12Unless required by applicable law or agreed to in writing, software
13distributed under the License is distributed on an "AS IS" BASIS,
14WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15See the License for the specific language governing permissions and
16limitations under the License.
17*/
18
19#![doc(html_root_url = "https://docs.rs/mju-bits/0.3.0")]
20
21//! `#[no_std]` implementation of typed bitfield access for `u8`, `u16`, `u32`, `u64` and `usize`.
22//!
23//!
24//! Usage:
25//!
26//! ```
27//! use typenum::*;
28//! use mju_bits::*;
29//!
30//! struct RegisterMarker;
31//! type Register = Storage<RegisterMarker, u32>;
32//! type RegisterAll = BitField<Register, U0, U31>;
33//! type RegisterFieldA = BitField<Register, U0, U7>;
34//! type RegisterFieldB = BitField<Register, U8, U24>;
35//!
36//! let mut reg = Register::new();
37//! reg.set::<RegisterFieldA>(0x56);
38//! reg.set::<RegisterFieldB>(0x1234);
39//! assert_eq!(reg.get::<RegisterAll>(), 0x00123456);
40//! ```
41//!
42//! The Storage type ensures that a field may only be used with its corresponding storage.
43//!
44//! For example, this won't compile:
45//!
46//! ```compilefail
47//! use mju_bits::*;
48//!
49//! struct FooMarker;
50//! type Foo = Storage<FooMarker, u8>;
51//! type FooField = BitField<Foo, U0, U1>;
52//!
53//! struct BarMarker;
54//! type Bar = Storage<BarMarker, u8>;
55//!
56//! let bar = Bar::new();
57//! bar.get::<FooField>();
58//! ```
59
60#![no_std]
61
62pub mod bitfield;
63pub mod storage;
64
65pub use bitfield::*;
66pub use storage::*;
67
68#[cfg(test)]
69mod test {
70 use super::*;
71 use typenum::{
72 U0, U3, U4, U7, U8, U15, U16, U31, U32, U63,
73 };
74
75 macro_rules! test {
76 ($name:ident, $type:ident, $lo0:ident, $lo1:ident, $hi0:ident, $hi1:ident, $lo:expr, $hi:expr, $all:expr) => {
77 #[test]
78 fn $name() {
79 struct RegisterMarker;
80 type Register = Storage<RegisterMarker, $type>;
81 type RegisterAll = BitField<Register, $lo0, $hi1>;
82 type RegisterFieldLo = BitField<Register, $lo0, $lo1>;
83 type RegisterFieldHi = BitField<Register, $hi0, $hi1>;
84
85 let mut reg = Register::new();
86 assert_eq!(reg.get::<RegisterFieldLo>(), 0);
87 assert_eq!(reg.get::<RegisterFieldHi>(), 0);
88
89 reg.set::<RegisterFieldLo>($lo);
90 assert_eq!(reg.get::<RegisterFieldLo>(), $lo);
91 assert_eq!(reg.get::<RegisterFieldHi>(), 0);
92
93 reg.set::<RegisterFieldHi>($hi);
94 assert_eq!(reg.get::<RegisterFieldLo>(), $lo);
95 assert_eq!(reg.get::<RegisterFieldHi>(), $hi);
96
97 assert_eq!(reg.get::<RegisterAll>(), $all);
98 }
99 };
100 }
101
102 test!(
103 test_u8, u8,
104 U0, U3,
105 U4, U7,
106 0b1100, 0b1010,
107 0b10101100
108 );
109
110 test!(
111 test_u16, u16,
112 U0, U7,
113 U8, U15,
114 0b11110000, 0b10101010,
115 0b10101010_11110000
116 );
117
118 test!(
119 test_u32, u32,
120 U0, U15,
121 U16, U31,
122 0b11111111_00000000, 0b10101010_10101010,
123 0b10101010_10101010_11111111_00000000
124 );
125
126 #[cfg(target_pointer_width="64")]
127 test!(
128 test_u64, u64,
129 U0, U31,
130 U32, U63,
131 0b11111111_11111111_00000000_00000000, 0b10101010_10101010_10101010_10101010,
132 0b10101010_10101010_10101010_10101010_11111111_11111111_00000000_00000000
133 );
134}