Skip to main content

stackforge_core/utils/
bits.rs

1//! Bitwise operations and byte order conversions.
2
3/// Extract bits from a byte.
4#[inline]
5#[must_use]
6pub fn extract_bits(byte: u8, start: u8, len: u8) -> u8 {
7    (byte >> (8 - start - len)) & ((1 << len) - 1)
8}
9
10/// Set bits in a byte.
11#[inline]
12pub fn set_bits(byte: &mut u8, start: u8, len: u8, value: u8) {
13    let mask = ((1u8 << len) - 1) << (8 - start - len);
14    *byte = (*byte & !mask) | ((value << (8 - start - len)) & mask);
15}
16
17/// Convert a u16 to big-endian bytes.
18#[inline]
19#[must_use]
20pub const fn u16_to_be(value: u16) -> [u8; 2] {
21    value.to_be_bytes()
22}
23
24/// Convert a u32 to big-endian bytes.
25#[inline]
26#[must_use]
27pub const fn u32_to_be(value: u32) -> [u8; 4] {
28    value.to_be_bytes()
29}
30
31/// Convert big-endian bytes to u16.
32#[inline]
33#[must_use]
34pub const fn be_to_u16(bytes: [u8; 2]) -> u16 {
35    u16::from_be_bytes(bytes)
36}
37
38/// Convert big-endian bytes to u32.
39#[inline]
40#[must_use]
41pub const fn be_to_u32(bytes: [u8; 4]) -> u32 {
42    u32::from_be_bytes(bytes)
43}
44
45#[cfg(test)]
46mod tests {
47    use super::*;
48
49    #[test]
50    fn test_extract_bits() {
51        let byte = 0b1010_0110;
52        assert_eq!(extract_bits(byte, 0, 4), 0b1010);
53        assert_eq!(extract_bits(byte, 4, 4), 0b0110);
54        assert_eq!(extract_bits(byte, 2, 4), 0b1001);
55    }
56
57    #[test]
58    fn test_set_bits() {
59        let mut byte = 0b0000_0000;
60        set_bits(&mut byte, 0, 4, 0b1010);
61        assert_eq!(byte, 0b1010_0000);
62
63        set_bits(&mut byte, 4, 4, 0b0110);
64        assert_eq!(byte, 0b1010_0110);
65    }
66}