aarchmrs_types/
bit_value.rs1#[derive(Copy, Clone, Debug, Default, Hash, PartialEq, Eq)]
11pub struct BitValue<const BITS: u32>(pub u32);
12
13impl<const BITS: u32> BitValue<BITS> {
14 #[inline]
15 pub const fn new_u32(nested: u32) -> Self {
16 debug_assert!({
17 let upper_bits = i32::BITS - BITS;
18 nested == (nested << upper_bits) >> upper_bits
19 });
20
21 Self(nested)
22 }
23
24 #[inline]
25 pub const fn new_i32(nested: i32) -> Self {
26 let upper_bits = i32::BITS - BITS;
27 debug_assert!(nested == ((nested << upper_bits) >> upper_bits));
30
31 let mask = u32::MAX >> upper_bits;
32 let nested = nested as u32;
33 Self(nested & mask)
34 }
35
36 #[inline]
37 pub const fn into_inner(self) -> u32 {
38 self.0
39 }
40}
41
42impl<const BITS: u32> From<BitValue<BITS>> for u32 {
43 #[inline]
44 fn from(value: BitValue<BITS>) -> Self {
45 value.0
46 }
47}
48
49impl<const BITS: u32> From<u32> for BitValue<BITS> {
50 #[inline]
51 fn from(value: u32) -> Self {
52 Self::new_u32(value)
53 }
54}
55
56impl<const BITS: u32> From<i32> for BitValue<BITS> {
57 #[inline]
58 fn from(value: i32) -> Self {
59 Self::new_i32(value)
60 }
61}
62
63impl<const BITS: u32> From<u16> for BitValue<BITS> {
64 #[inline]
65 fn from(value: u16) -> Self {
66 Self::new_u32(value as _)
67 }
68}
69
70impl<const BITS: u32> From<i16> for BitValue<BITS> {
71 #[inline]
72 fn from(value: i16) -> Self {
73 Self::new_i32(value as _)
74 }
75}
76
77impl<const BITS: u32> From<u8> for BitValue<BITS> {
78 #[inline]
79 fn from(value: u8) -> Self {
80 Self::new_u32(value as _)
81 }
82}
83
84impl<const BITS: u32> From<i8> for BitValue<BITS> {
85 #[inline]
86 fn from(value: i8) -> Self {
87 Self::new_i32(value as _)
88 }
89}
90
91impl From<bool> for BitValue<1> {
92 #[inline]
93 fn from(value: bool) -> Self {
94 Self::new_u32(value as u32)
95 }
96}
97
98#[cfg(test)]
99mod tests {
100 use super::*;
101
102 #[test]
103 fn test_valid_u32() {
104 let _ = BitValue::<8>::new_u32(255);
105 }
106
107 #[test]
108 fn test_valid_u32_1() {
109 let _ = BitValue::<8>::new_u32(42);
110 }
111
112 #[test]
113 #[cfg_attr(debug_assertions, should_panic)]
114 fn test_invalid_u32() {
115 let _ = BitValue::<8>::new_u32(256);
116 }
117
118 #[test]
119 fn test_valid_i32() {
120 let _ = BitValue::<8>::new_i32(42);
121 }
122
123 #[test]
124 fn test_valid_i32_max() {
125 let _ = BitValue::<8>::new_i32(i8::MAX.into());
126 }
127
128 #[test]
129 fn test_valid_i32_min() {
130 let _ = BitValue::<8>::new_i32(i8::MIN.into());
131 }
132
133 #[test]
134 #[cfg_attr(debug_assertions, should_panic)]
135 fn test_invalid_i32_max() {
136 let max: i32 = i8::MAX.into();
137 let _ = BitValue::<8>::new_i32(max + 1);
138 }
139
140 #[test]
141 #[cfg_attr(debug_assertions, should_panic)]
142 fn test_invalid_i32_min() {
143 let min: i32 = i8::MIN.into();
144 let _ = BitValue::<8>::new_i32(min - 1);
145 }
146
147 #[test]
148 #[cfg_attr(debug_assertions, should_panic)]
149 fn test_invalid_i32_i16max() {
150 let max: i32 = i16::MAX.into();
151 let _ = BitValue::<8>::new_i32(max);
152 }
153
154 #[test]
155 #[cfg_attr(debug_assertions, should_panic)]
156 fn test_invalid_i32_i16min() {
157 let min: i32 = i16::MIN.into();
158 let _ = BitValue::<8>::new_i32(min);
159 }
160}