1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
//! Utilites for working with bits and bitflags.
use bitflags::BitFlags;
/// A group of bits within a byte. Provides utilities for extracting and setting the
/// selected bits.
#[derive(Debug, Copy, Clone)]
#[repr(transparent)]
pub struct BitGroup(pub u8);
impl BitGroup {
/// Masks the given value down to just these bits without applying any shifting.
#[inline]
pub const fn filter(self, val: u8) -> u8 {
val & self.0
}
/// Extract these bits from the given u8 value.
///
/// The return value will be the input `val` masked to only the bits in this BitGroup
/// and shifted over so the right-most bit of the group is in the 0th bit index.
#[inline]
pub const fn extract(self, val: u8) -> u8 {
(val & self.0) >> self.0.trailing_zeros()
}
/// Extract these bits from the given u8 value, applying sign-extension to them.
///
/// The return value will be the input `val` masked to only the bits in this BitGroup
/// and shifted over so the right-most bit of the group is in the 0th bit index.
#[inline]
pub const fn extract_signed(self, val: u8) -> i8 {
(((val & self.0) << self.0.leading_zeros()) as i8)
>> (self.0.leading_zeros() + self.0.trailing_zeros())
}
/// Extract this value as a boolean. Returns true if the value within the portion of
/// the `val` covered by this [`BitGroup`] is non-zero.
#[inline]
pub const fn extract_bool(self, val: u8) -> bool {
(val & self.0) != 0
}
/// Write `val` to the part of `dest` represented by this [`BitGroup`].
///
/// Shift `val` to the left so that it starts at the same point as this `BitGroup` and
/// then apply it to `dest` with a mask.
#[inline]
pub fn apply(self, dest: &mut u8, val: u8) {
*dest = (*dest & !self.0) | ((val << self.0.trailing_zeros()) & self.0);
}
/// Write `val` to this bits-based value.
#[inline]
pub fn apply_bits<B>(self, dest: &mut B, val: u8)
where
B: BitFlags<Bits = u8>,
{
let mut bits = dest.bits();
self.apply(&mut bits, val);
*dest = B::from_bits_truncate(bits);
}
}