bits_io/
bit_types.rs

1use bitvec::{
2    order::Msb0,
3    ptr::{BitPtr, BitSpanError, Mut},
4};
5
6// We only want to support `u8` as a `BitStore` for our `BitSlice` types, but because of bitvec's
7// storage aliasing to support mutable `BitSlice`s whose backing bytes overlap, we need to also
8// support `BitSafeU8` as a `BitStore`.  We define our own `BitStore` and implement it only to
9// support `u8` and `BitSafeU8`
10mod sealed {
11    pub trait Sealed {}
12    impl Sealed for u8 {}
13    impl Sealed for bitvec::access::BitSafeU8 {}
14}
15
16// We use sealed above to ensure that these are the only two possible impls of our `BitStore`
17// wrapper.  This makes the logic in `byte_order` more straightforward because the compiler knows
18// that the two specialized implementations of `WriteU32ToBits` are the _only_ possible values.
19// TODO:: I'm not sure if this trait needs to be public or not.
20pub trait BitStore: bitvec::store::BitStore + sealed::Sealed {}
21
22impl BitStore for u8 {}
23impl BitStore for bitvec::access::BitSafeU8 {}
24
25pub type BitSlice<O = u8> = bitvec::slice::BitSlice<O, bitvec::order::Msb0>;
26
27pub type BitVec = bitvec::vec::BitVec<u8, bitvec::order::Msb0>;
28
29/// Create a mutable BitSlice from raw parts.  This is a wrapper of a bitvec function and just
30/// hardcodes the storage to u8 and order to Msb0
31///
32/// # Errors
33///
34/// This function will return an error if len is too large, or if data is ill-formed. This fails if
35/// it has an error while encoding the &mut BitSlice, and succeeds if it is able to produce a
36/// correctly encoded value.
37///
38/// # Safety
39/// See bitvec::slice::from_raw_parts_mut
40///
41/// .
42#[inline]
43pub unsafe fn from_raw_parts_mut<'a>(
44    data: BitPtr<Mut, u8, Msb0>,
45    len: usize,
46) -> Result<&'a mut BitSlice, BitSpanError<u8>> {
47    bitvec::slice::from_raw_parts_mut::<u8, Msb0>(data, len)
48}
49
50// Having to include the 'use' statements in the nested calls below is pretty annoying, but the
51// bitvec macros generate some annoying linter complaints when a fully-qualified path is used.
52
53#[macro_export]
54macro_rules! bits {
55    ($value:expr; $len:expr) => {{
56        use $crate::internal::bitvec::order::Msb0;
57        ($crate::internal::bitvec::bits![u8, Msb0; $value; $len])
58    }};
59    (mut $value:expr; $len:expr) => {{
60        use $crate::internal::bitvec::order::Msb0;
61        ($crate::internal::bitvec::bits![mut u8, Msb0; $value; $len])
62    }};
63    (mut $($bit:expr),* $(,)?) => {{
64        use $crate::internal::bitvec::order::Msb0;
65        ($crate::internal::bitvec::bits![mut u8, Msb0; $($bit),*])
66    }};
67    ($($bit:expr),* $(,)?) => {{
68        use $crate::internal::bitvec::order::Msb0;
69        ($crate::internal::bitvec::bits![u8, Msb0; $($bit),*])
70    }};
71}
72
73#[macro_export]
74macro_rules! bitvec {
75    // Repeat value form: bitvec_u8![value; len]
76    ($value:expr; $len:expr) => {{
77        use $crate::internal::bitvec::order::Msb0;
78        ($crate::internal::bitvec::bitvec!(u8, Msb0; $value; $len))
79    }};
80    // List of explicit bits: bitvec_u8![1, 0, 1, 1]
81    ($($bit:expr),* $(,)?) => {
82        use $crate::internal::bitvec::order::Msb0;
83        ($crate::internal::bitvec::bitvec!(u8, Msb0; $($bit),*))
84    };
85}