1#![cfg(feature = "bitvec")]
2use bitvec::prelude::{BitOrder, BitSlice, Lsb0};
8use core::marker::PhantomData;
9use core::ops::{Deref, DerefMut};
10use heapless::Vec as HVec;
11use std::borrow::{Borrow, BorrowMut};
12
13use crate::AnyBitVec;
14
15#[derive(Debug)]
53pub struct HeaplessBitVec<const N: usize, O: BitOrder = Lsb0> {
54 bytes: HVec<u8, N>,
55 bit_len: usize,
57 _order: PhantomData<O>,
58}
59
60impl<const N: usize, O: BitOrder> Clone for HeaplessBitVec<N, O> {
61 fn clone(&self) -> Self {
62 Self {
63 bytes: self.bytes.clone(),
64 bit_len: self.bit_len,
65 _order: PhantomData,
66 }
67 }
68}
69
70impl<const N: usize, O: BitOrder> HeaplessBitVec<N, O> {
71 pub fn new() -> Self {
73 const {
74 assert!(
75 std::mem::size_of::<Self>() <= 16 * 1024,
76 "HeaplessBitVec is too large! The struct size exceeds the 16KB limit. Reduce N."
77 );
78 }
79 Self {
80 bytes: HVec::new(),
81 bit_len: 0,
82 _order: PhantomData,
83 }
84 }
85
86 pub fn len(&self) -> usize {
88 self.bit_len
89 }
90
91 pub fn is_empty(&self) -> bool {
93 self.bit_len == 0
94 }
95
96 pub fn push(&mut self, val: bool) -> Result<(), bool> {
98 let bit_idx = self.bit_len % 8;
99
100 if bit_idx == 0 {
102 if self.bytes.push(0).is_err() {
103 return Err(val); }
105 }
106
107 if val {
108 self.set(self.bit_len, true);
109 }
110
111 self.bit_len += 1;
112 Ok(())
113 }
114
115 pub fn pop(&mut self) -> Option<bool> {
117 if self.bit_len == 0 {
118 return None;
119 }
120
121 let val = self.get(self.bit_len - 1).unwrap();
122 self.bit_len -= 1;
123
124 if self.bit_len % 8 == 0 {
126 self.bytes.pop();
127 }
128
129 Some(val)
130 }
131
132 pub fn get(&self, index: usize) -> Option<bool> {
134 if index >= self.bit_len {
135 return None;
136 }
137 let byte_idx = index / 8;
138 let bit_idx = index % 8;
139
140 use bitvec::slice::BitSlice;
141 let byte = self.bytes[byte_idx];
142 let slice = BitSlice::<u8, O>::from_element(&byte);
143 slice.get(bit_idx).as_deref().copied()
144 }
145
146 pub fn set(&mut self, index: usize, value: bool) {
148 if index >= self.bit_len && index != self.bit_len {
149 panic!("Index out of bounds");
150 }
151 let byte_idx = index / 8;
152 let bit_idx = index % 8;
153
154 use bitvec::slice::BitSlice;
155 let byte = &mut self.bytes[byte_idx];
156 let slice = BitSlice::<u8, O>::from_element_mut(byte);
157 slice.set(bit_idx, value);
158 }
159
160 pub fn as_raw_slice(&self) -> &[u8] {
162 &self.bytes
163 }
164
165 pub fn as_bitslice(&self) -> &BitSlice<u8, O> {
167 let slice = BitSlice::<u8, O>::from_slice(self.bytes.as_slice());
168 &slice[..self.bit_len]
169 }
170
171 pub fn as_bitslice_mut(&mut self) -> &mut BitSlice<u8, O> {
173 let slice = BitSlice::<u8, O>::from_slice_mut(self.bytes.as_mut_slice());
174 &mut slice[..self.bit_len]
175 }
176}
177
178impl<const N: usize, O: BitOrder> Deref for HeaplessBitVec<N, O> {
179 type Target = BitSlice<u8, O>;
180
181 fn deref(&self) -> &Self::Target {
182 self.as_bitslice()
183 }
184}
185
186impl<const N: usize, O: BitOrder> DerefMut for HeaplessBitVec<N, O> {
187 fn deref_mut(&mut self) -> &mut Self::Target {
188 self.as_bitslice_mut()
189 }
190}
191
192impl<const N: usize, O: BitOrder> Borrow<BitSlice<u8, O>> for HeaplessBitVec<N, O> {
193 fn borrow(&self) -> &BitSlice<u8, O> {
194 self.as_bitslice()
195 }
196}
197
198impl<const N: usize, O: BitOrder> BorrowMut<BitSlice<u8, O>> for HeaplessBitVec<N, O> {
199 fn borrow_mut(&mut self) -> &mut BitSlice<u8, O> {
200 self.as_bitslice_mut()
201 }
202}
203
204impl<const N: usize, O: BitOrder> Default for HeaplessBitVec<N, O> {
205 fn default() -> Self {
206 Self::new()
207 }
208}
209
210impl<const N: usize, O: BitOrder> AnyBitVec for HeaplessBitVec<N, O> {
211 fn len(&self) -> usize {
212 self.len()
213 }
214
215 fn get(&self, index: usize) -> Option<bool> {
216 self.get(index)
217 }
218}
219
220#[cfg(test)]
221mod heapless_bitvec_basic_tests {
222 use super::*;
223 use bitvec::prelude::{Lsb0, Msb0};
224
225 #[test]
226 fn test_heapless_bitvec_traits_bitslice() {
227 use std::borrow::BorrowMut;
228 let mut bv: HeaplessBitVec<1, Lsb0> = HeaplessBitVec::new();
229 bv.push(true).unwrap();
230 bv.push(false).unwrap();
231
232 let slice: &bitvec::slice::BitSlice<u8, Lsb0> = &bv;
234 assert_eq!(slice.len(), 2);
235 assert_eq!(slice[0], true);
236
237 let slice_mut: &mut bitvec::slice::BitSlice<u8, Lsb0> = bv.borrow_mut();
239 slice_mut.set(1, true);
240 assert_eq!(bv.get(1), Some(true));
241 }
242
243 #[test]
244 fn test_heapless_bitvec_stack_ops_lsb0() {
245 let mut bv: HeaplessBitVec<1, Lsb0> = HeaplessBitVec::new();
246 bv.push(true).unwrap(); bv.push(false).unwrap(); bv.push(true).unwrap(); assert_eq!(bv.as_raw_slice()[0], 0b00000101);
250 assert_eq!(bv.get(0), Some(true));
251 assert_eq!(bv.get(1), Some(false));
252 assert_eq!(bv.get(2), Some(true));
253 }
254
255 #[test]
256 fn test_heapless_bitvec_stack_ops_msb0() {
257 let mut bv: HeaplessBitVec<1, Msb0> = HeaplessBitVec::new();
258 bv.push(true).unwrap(); bv.push(false).unwrap(); bv.push(true).unwrap(); assert_eq!(bv.as_raw_slice()[0], 0b10100000);
262 assert_eq!(bv.get(0), Some(true));
263 assert_eq!(bv.get(1), Some(false));
264 assert_eq!(bv.get(2), Some(true));
265 }
266
267 #[test]
268 fn test_heapless_bitvec_stack_ops_set_get() {
269 let mut bv: HeaplessBitVec<1, Lsb0> = HeaplessBitVec::new();
270 for _ in 0..8 {
271 bv.push(false).unwrap();
272 }
273 bv.set(0, true);
274 bv.set(7, true);
275 assert_eq!(bv.get(0), Some(true));
276 assert_eq!(bv.get(7), Some(true));
277 assert_eq!(bv.get(1), Some(false));
278 }
279
280 #[test]
281 fn test_heapless_bitvec_stack_ops_empty_len() {
282 let mut bv: HeaplessBitVec<1, Lsb0> = HeaplessBitVec::new();
283 assert!(bv.is_empty());
284 bv.push(true).unwrap();
285 assert!(!bv.is_empty());
286 assert_eq!(bv.len(), 1);
287 }
288
289 #[test]
290 fn test_heapless_bitvec_traits_clone_default() {
291 let bv1: HeaplessBitVec<1, Lsb0> = HeaplessBitVec::default();
292 let mut bv2 = bv1.clone();
293 bv2.push(true).unwrap();
294 assert_eq!(bv2.len(), 1);
295 assert_eq!(bv1.len(), 0);
296 }
297
298 #[test]
299 fn test_heapless_bitvec_stack_ops_boundary_fill() {
300 let mut bv: HeaplessBitVec<1, Lsb0> = HeaplessBitVec::new();
301 for _ in 0..8 {
302 bv.push(true).unwrap();
303 }
304 assert!(bv.push(true).is_err());
305 assert_eq!(bv.len(), 8);
306 }
307
308 #[test]
309 fn test_heapless_bitvec_stack_ops_pop() {
310 let mut bv: HeaplessBitVec<1, Lsb0> = HeaplessBitVec::new();
311 bv.push(true).unwrap();
312 bv.push(false).unwrap();
313 assert_eq!(bv.pop(), Some(false));
314 assert_eq!(bv.pop(), Some(true));
315 assert_eq!(bv.pop(), None);
316 }
317
318 #[test]
319 fn test_heapless_bitvec_traits_any_bitvec_impl() {
320 let mut bv: HeaplessBitVec<1, Lsb0> = HeaplessBitVec::new();
321 bv.push(true).unwrap();
322
323 let any: &dyn AnyBitVec = &bv;
324 assert_eq!(any.len(), 1);
325 assert_eq!(any.get(0), Some(true));
326 }
327}
328
329#[cfg(test)]
330mod heapless_bitvec_coverage_tests {
331 use super::*;
332 use bitvec::prelude::Lsb0;
333 use std::borrow::Borrow;
334
335 #[test]
336 #[should_panic(expected = "Index out of bounds")]
337 fn test_set_out_of_bounds() {
338 let mut bv: HeaplessBitVec<1, Lsb0> = HeaplessBitVec::new();
339 bv.set(10, true);
340 }
341
342 #[test]
343 fn test_deref_mut_and_borrow() {
344 let mut bv: HeaplessBitVec<1, Lsb0> = HeaplessBitVec::new();
345 bv.push(true).unwrap();
346
347 use core::ops::DerefMut;
349 let slice = bv.deref_mut();
350 slice.set(0, false);
351
352 let borrowed: &bitvec::slice::BitSlice<u8, Lsb0> = bv.borrow();
354 assert_eq!(borrowed.len(), 1);
355 }
356}