Skip to main content

bit_buf/
lib.rs

1#![no_std]
2#![warn(missing_docs)]
3
4//! See <code>[BitBuf]::[from()][BitBuf::from]</code>, [`Storage`]/[`StorageMut`], and <code>[BitBuf]::{read,write}_*()</code>
5//!
6//! | Term | Definition |
7//! | - | - |
8//! | UB | [Undefined Behaviour](https://doc.rust-lang.org/reference/behavior-considered-undefined.html) |
9//! | BE | [Big Endian](https://en.wikipedia.org/wiki/Endianness) |
10//! | LE | [Little Endian](https://en.wikipedia.org/wiki/Endianness) |
11//!
12//! Any usage of `pos`/`offset` implies bits rather than bytes
13
14mod buf;
15mod error;
16
17mod read;
18mod write;
19
20pub use buf::BitBuf;
21pub use error::Error;
22
23/// Returned from checked operations
24pub type Result<T> = core::result::Result<T, Error>;
25
26/// This trait must be implemented for types from which you wish to use `read_*` operations with
27pub trait Storage {
28  /// Get the bytes that represent this type
29  fn as_bytes(&self) -> &[u8];
30}
31
32/// This trait must be implemented for types from which you wish to use `write_*` operations with
33pub trait StorageMut: Storage {
34  /// Get the bytes that represent this type
35  fn as_bytes_mut(&mut self) -> &mut [u8];
36}
37
38impl<const N: usize> Storage for [u8; N] {
39  #[inline(always)]
40  fn as_bytes(&self) -> &[u8] {
41    self
42  }
43}
44
45impl<const N: usize> StorageMut for [u8; N] {
46  #[inline(always)]
47  fn as_bytes_mut(&mut self) -> &mut [u8] {
48    self
49  }
50}
51
52impl<const N: usize> Storage for &[u8; N] {
53  #[inline(always)]
54  fn as_bytes(&self) -> &[u8] {
55    *self
56  }
57}
58
59impl<const N: usize> Storage for &mut [u8; N] {
60  #[inline(always)]
61  fn as_bytes(&self) -> &[u8] {
62    *self
63  }
64}
65
66impl<const N: usize> StorageMut for &mut [u8; N] {
67  #[inline(always)]
68  fn as_bytes_mut(&mut self) -> &mut [u8] {
69    *self
70  }
71}
72
73impl Storage for &[u8] {
74  #[inline(always)]
75  fn as_bytes(&self) -> &[u8] {
76    self
77  }
78}
79
80impl Storage for &mut [u8] {
81  #[inline(always)]
82  fn as_bytes(&self) -> &[u8] {
83    self
84  }
85}
86
87impl StorageMut for &mut [u8] {
88  #[inline(always)]
89  fn as_bytes_mut(&mut self) -> &mut [u8] {
90    self
91  }
92}
93
94macro_rules! ensure {
95  ($cond:expr $(,)? $(; $($tt:tt)*)?) => {
96    #[allow(clippy::macro_metavars_in_unsafe)]
97    unsafe {
98      $(
99        #[cfg(test)]
100        ::core::assert!($cond, $($tt)*);
101      )?
102
103      $(
104        #[cfg(not(test))]
105        ::core::debug_assert!($cond, $($tt)*);
106      )?
107
108      ::core::hint::assert_unchecked($cond);
109    }
110  };
111}
112
113use ensure;