scale_bits/bits/bits.rs
1// Copyright (C) 2024 Parity Technologies (UK) Ltd. (admin@parity.io)
2// This file is a part of the scale-value crate.
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16#![allow(clippy::module_inception)]
17
18use alloc::vec::Vec;
19use codec::{Compact, Decode, Encode};
20
21/// This macro makes it trivial to construct [`Bits`] from either 0 and 1 bit
22/// literals, or booleans.
23///
24/// ```rust
25/// use scale_bits::bits;
26///
27/// // Using 1 and 0 literals to represent the bits:
28/// let bits = bits![1,1,0,1,0,1];
29/// assert_eq!(bits.to_vec(), vec![true, true, false, true, false, true]);
30///
31/// // Using true and false to represent the bits:
32/// let bits = bits![true, true, false, true, false, true];
33/// assert_eq!(bits.to_vec(), vec![true, true, false, true, false, true]);
34///
35/// // These don't have to be literals:
36/// let t = true;
37/// let f = false;
38/// let bits = bits![t,t,f,t,f,t];
39/// assert_eq!(bits.to_vec(), vec![true, true, false, true, false, true]);
40///
41/// # // Empty bits should be fine:
42/// # assert_eq!(bits![].to_vec(), Vec::<bool>::new());
43/// #
44/// # // Trailing ',' should be fine:
45/// # assert_eq!(bits![0,].to_vec(), vec![false]);
46/// # assert_eq!(bits![1,].to_vec(), vec![true]);
47/// # assert_eq!(bits![0,1,].to_vec(), vec![false, true]);
48/// # assert_eq!(bits![false,].to_vec(), vec![false]);
49/// # assert_eq!(bits![true,].to_vec(), vec![true]);
50/// # assert_eq!(bits![false,true,].to_vec(), vec![false, true]);
51/// #
52/// # // We can mix bools and bits inc expressions
53/// # assert_eq!(bits![0,t,1,f].to_vec(), vec![false, true, true, false]);
54/// ```
55#[macro_export]
56macro_rules! bits {
57 ($($val:tt),* $(,)*) => {{
58 #[allow(unused_mut)]
59 let mut bits = $crate::bits::Bits::new();
60 $crate::bits!(__internal__ bits: $($val),*);
61 bits
62 }};
63 (__internal__ $bits:ident: 1 $(,$rest:tt)* $(,)?) => {{
64 $bits.push(true);
65 $crate::bits!(__internal__ $bits: $($rest,)*);
66 }};
67 (__internal__ $bits:ident: 0 $(,$rest:tt)* $(,)?) => {{
68 $bits.push(false);
69 $crate::bits!(__internal__ $bits: $($rest,)*);
70 }};
71 (__internal__ $bits:ident: $bool:expr $(,$rest:tt)* $(,)?) => {{
72 $bits.push($bool);
73 $crate::bits!(__internal__ $bits: $($rest,)*);
74 }};
75 (__internal__ $bits:ident: $(,)?) => {{
76 // Catch the "empty" case and end.
77 }};
78}
79
80/// This represents a sequence of boolean values, packed into bits.
81///
82/// One of the defining features of this type is that it SCALE encodes and decodes into an
83/// identical representation to a `BitVec<u8, Lsb0>`, and has matching a [`scale_info::TypeInfo`]
84/// implementation to align with this. This allows it to be used in place of `BitVec<u8, Lsb0>`
85/// when you need something with an identical SCALE representation and a simple API and don't wish
86/// to pull in the `bitvec` crate.
87///
88/// In addition to this, we can use the [`crate::scale::Format`] type to encode and decode [`Bits`]
89/// in the same way as `BitVec`'s do with order types of `Lsb0` and `Msb0`, and store types of
90/// `u8`, `u16`, and `u32`.
91///
92/// With the `serde` feature enabled we can also serialize and seserialize [`Bits`] from sequences
93/// of booleans.
94///
95/// # Example
96///
97/// ```rust
98/// use scale_bits::bits::Bits;
99///
100/// let mut bits = Bits::new();
101/// bits.push(true);
102/// bits.push(false);
103/// bits.push(false);
104///
105/// assert_eq!(bits.len(), 3);
106/// ```
107///
108/// Converting to and from `Vec<bool>`:
109///
110/// ```rust
111/// use scale_bits::bits::Bits;
112///
113/// let bools = vec![true, false, true, false, true];
114/// let bits: Bits = bools.into_iter().collect();
115///
116/// let new_bools: Vec<bool> = bits.into_iter().collect();
117/// assert_eq!(new_bools, vec![true, false, true, false, true]);
118/// ```
119#[derive(Clone, PartialEq, Eq, Debug, Default)]
120pub struct Bits {
121 pub(crate) storage: Vec<u8>,
122 // Number of bits stored in the last byte.
123 pub(crate) bits_in_last_byte: usize,
124}
125
126impl Bits {
127 /// Create a new empty list of bits. This does not allocate.
128 pub fn new() -> Self {
129 Self::default()
130 }
131
132 /// Create a new empty list of bits. Pre-allocates enough space for
133 /// the number of bits provided here.
134 pub fn with_capacity(num_bits: usize) -> Self {
135 let mut num_bytes = num_bits / 8;
136
137 // the above division rounds down, so add another byte
138 // if we don't have an exact multiple of 8 num_bits.
139 let is_exact_multiple_of_8 = num_bits & 0b111 == 0;
140 if !is_exact_multiple_of_8 {
141 num_bytes += 1;
142 }
143
144 Bits { storage: Vec::with_capacity(num_bytes), bits_in_last_byte: 0 }
145 }
146
147 /// Returns true if no bits are stored.
148 ///
149 /// # Example
150 ///
151 /// ```rust
152 /// use scale_bits::bits::Bits;
153 ///
154 /// let mut bits = Bits::new();
155 /// assert!(bits.is_empty());
156 ///
157 /// bits.push(true);
158 /// assert!(!bits.is_empty());
159 ///
160 /// bits.pop();
161 /// assert!(bits.is_empty());
162 /// ```
163 pub fn is_empty(&self) -> bool {
164 self.storage.is_empty()
165 }
166
167 /// Return the number of bits stored.
168 ///
169 /// # Example
170 ///
171 /// ```rust
172 /// use scale_bits::bits::Bits;
173 ///
174 /// let mut bits = Bits::new();
175 /// assert_eq!(bits.len(), 0);
176 ///
177 /// bits.push(true);
178 /// bits.push(false);
179 /// bits.push(true);
180 /// assert_eq!(bits.len(), 3);
181 ///
182 /// bits.pop();
183 /// bits.pop();
184 /// assert_eq!(bits.len(), 1);
185 pub fn len(&self) -> usize {
186 let len = self.storage.len();
187
188 // -1 below so explicit return is zero.
189 if len == 0 {
190 return 0;
191 }
192
193 // minus the last byte worth and then add on only the bits we've
194 // stored so far in it.
195 (len - 1) * 8 + self.bits_in_last_byte
196 }
197
198 /// Push new bits to the end of the list.
199 ///
200 /// # Example
201 ///
202 /// ```rust
203 /// use scale_bits::{ bits::Bits, bits };
204 ///
205 /// let mut bs = Bits::new();
206 /// bs.push(true);
207 /// bs.push(false);
208 /// bs.push(true);
209 ///
210 /// assert_eq!(bs, bits![1,0,1]);
211 /// ```
212 pub fn push(&mut self, b: bool) {
213 let bit_val: u8 = match b {
214 true => 1,
215 false => 0,
216 };
217
218 match self.bits_in_last_byte {
219 // empty storage is the only time we see 0
220 // and a full last byte is when we see 8. In
221 // both cases we start a new byte with our 1
222 // value.
223 0 | 8 => {
224 self.storage.push(bit_val);
225 self.bits_in_last_byte = 1;
226 }
227 // Otherwise, get the last byte and add our
228 // bit in at the right offset.
229 n => {
230 let byte = self.storage.last_mut().expect("should be a byte");
231 *byte |= bit_val << n;
232 self.bits_in_last_byte += 1;
233 }
234 }
235 }
236
237 /// Remove bits from the end of the list, returning them
238 /// if they are present.
239 ///
240 /// # Example
241 ///
242 /// ```rust
243 /// use scale_bits::{ bits::Bits, bits };
244 ///
245 /// let mut bs = bits![true, false, true, true];
246 /// assert_eq!(bs.pop(), Some(true));
247 /// assert_eq!(bs.pop(), Some(true));
248 /// assert_eq!(bs.pop(), Some(false));
249 /// assert_eq!(bs.pop(), Some(true));
250 /// assert_eq!(bs.pop(), None);
251 /// assert_eq!(bs.pop(), None);
252 /// ```
253 pub fn pop(&mut self) -> Option<bool> {
254 let last_byte = self.storage.last_mut()?;
255
256 // 0 bits in last byte should never happen. minus one so:
257 // - bits == 1? don't right shift
258 // - bits == 2? shift the one bit before it off
259 // - .. and so on.
260 let right_shift_amount = self.bits_in_last_byte - 1;
261
262 let res = match (*last_byte >> right_shift_amount) & 1 {
263 1 => true,
264 0 => false,
265 _ => unreachable!("Can only be 0 or 1 owing to &1"),
266 };
267
268 // zero out the entry we're returning.
269 *last_byte ^= 1 << right_shift_amount;
270
271 // decrement our count of bits in the last byte:
272 self.bits_in_last_byte -= 1;
273 // if 0, remove the byte from the vec entirely:
274 if self.bits_in_last_byte == 0 {
275 self.storage.pop();
276 if self.storage.is_empty() {
277 self.bits_in_last_byte = 0;
278 } else {
279 self.bits_in_last_byte = 8;
280 }
281 }
282
283 Some(res)
284 }
285
286 /// Retrieve a bit at a given index, returning `None` if no bit exists
287 /// at that index.
288 ///
289 /// # Example
290 ///
291 /// ```rust
292 /// use scale_bits::bits;
293 ///
294 /// let bs = bits![true, false, true, true];
295 /// assert_eq!(bs.get(0), Some(true));
296 /// assert_eq!(bs.get(1), Some(false));
297 /// assert_eq!(bs.get(2), Some(true));
298 /// assert_eq!(bs.get(3), Some(true));
299 /// assert_eq!(bs.get(4), None);
300 /// ```
301 pub fn get(&self, idx: usize) -> Option<bool> {
302 // Bail early if empty storage since we'll expect
303 // at least one item to be stored below.
304 if self.storage.is_empty() {
305 return None;
306 }
307
308 let byte_idx = idx / 8;
309 // Dividing rounds down; taking last 3 bits gives us that precision back.
310 let bit_in_byte = idx & 0b111;
311
312 // Expect at least 1 item to be stored. If we're accessing
313 // the last byte, check we have stored enough bits in it.
314 if byte_idx == self.storage.len() - 1 && bit_in_byte >= self.bits_in_last_byte {
315 return None;
316 }
317
318 let byte = *self.storage.get(byte_idx)?;
319 match (byte >> bit_in_byte) & 1 {
320 0 => Some(false),
321 1 => Some(true),
322 _ => unreachable!("Can only be 0 or 1 owing to &1"),
323 }
324 }
325
326 /// Iterate over each bit in order, returning `true` or `false` for each.
327 ///
328 /// # Example
329 ///
330 /// ```rust
331 /// use scale_bits::bits;
332 ///
333 /// let bs = bits![true, false, true, true];
334 ///
335 /// let v: Vec<bool> = bs.iter().collect();
336 /// assert_eq!(v, vec![true, false, true, true]);
337 /// ```
338 pub fn iter(&'_ self) -> BitsIter<'_> {
339 BitsIter { pos: 0, bits: self }
340 }
341
342 /// Convert our bits into a `Vec<bool>`.
343 ///
344 /// # Example
345 ///
346 /// ```rust
347 /// use scale_bits::bits;
348 ///
349 /// let bs = bits![true, false, true, true].to_vec();
350 /// assert_eq!(bs, vec![true, false, true, true]);
351 /// ```
352 pub fn to_vec(self) -> Vec<bool> {
353 self.into_iter().collect()
354 }
355}
356
357impl core::iter::IntoIterator for Bits {
358 type Item = bool;
359 type IntoIter = BitsIntoIter;
360
361 fn into_iter(self) -> Self::IntoIter {
362 BitsIntoIter { pos: 0, bits: self }
363 }
364}
365
366/// Returned from calling `into_iter` on [`Bits`] via the
367/// [`core::iter::IntoIterator`] trait. Allows iteration over
368/// each stored bit.
369#[derive(Clone, Debug)]
370pub struct BitsIntoIter {
371 pos: usize,
372 bits: Bits,
373}
374
375impl Iterator for BitsIntoIter {
376 type Item = bool;
377 fn next(&mut self) -> Option<Self::Item> {
378 let next = self.bits.get(self.pos)?;
379 self.pos += 1;
380 Some(next)
381 }
382 fn size_hint(&self) -> (usize, Option<usize>) {
383 let len = self.bits.len() - self.pos;
384 (len, Some(len))
385 }
386}
387impl ExactSizeIterator for BitsIntoIter {}
388
389/// Returned from calling [`Bits::iter()`]. Allows iteration
390/// over each stored bit.
391#[derive(Copy, Clone, Debug)]
392pub struct BitsIter<'a> {
393 pos: usize,
394 bits: &'a Bits,
395}
396
397impl<'a> Iterator for BitsIter<'a> {
398 type Item = bool;
399 fn next(&mut self) -> Option<Self::Item> {
400 let next = self.bits.get(self.pos)?;
401 self.pos += 1;
402 Some(next)
403 }
404 fn size_hint(&self) -> (usize, Option<usize>) {
405 let len = self.bits.len() - self.pos;
406 (len, Some(len))
407 }
408}
409impl<'a> ExactSizeIterator for BitsIter<'a> {}
410
411impl core::iter::FromIterator<bool> for Bits {
412 fn from_iter<T: IntoIterator<Item = bool>>(iter: T) -> Self {
413 let iter = iter.into_iter();
414
415 // if we know the max size, make that space available.
416 // otherwise make at least the min size available.
417 let num_bits_to_alloc_for = match iter.size_hint() {
418 (_, Some(max)) => max,
419 (min, None) => min,
420 };
421
422 let mut bits = Bits::with_capacity(num_bits_to_alloc_for);
423 for b in iter {
424 bits.push(b);
425 }
426 bits
427 }
428}
429
430impl Decode for Bits {
431 fn decode<I: codec::Input>(input: &mut I) -> Result<Self, codec::Error> {
432 let len_bits = Compact::<u32>::decode(input)?.0 as usize;
433 let remainder = len_bits & 0b111;
434 let len = len_bits / 8 + if remainder > 0 { 1 } else { 0 };
435
436 // Just a little safety in case the encoding is naff/malicious; don't
437 // pre-allocate more than 1kb to store the bits into.
438 const MAX_PRE_ALLOC_BYTES: usize = 1024;
439 let prealloc_len = len.min(MAX_PRE_ALLOC_BYTES);
440 let mut storage = Vec::with_capacity(prealloc_len);
441
442 for _ in 0..len {
443 // THe "native" decoding/encoding of bits is equal to a BitVec<u8, Lsb0>.
444 // We just push/read the stored bytes to encode/decode to this format.
445 let byte = input.read_byte()?;
446 storage.push(byte);
447 }
448
449 // if length was greater than 0 and remainder == 0, bits_in_last_byte must be
450 // 8 (ie the last byte is full and no remainder). Else, bits_in_last_byte is
451 // equal to the remainder.
452 let bits_in_last_byte = if !storage.is_empty() && remainder == 0 { 8 } else { remainder };
453
454 Ok(Bits { storage, bits_in_last_byte })
455 }
456}
457
458impl Encode for Bits {
459 fn size_hint(&self) -> usize {
460 self.encoded_size()
461 }
462
463 fn encode(&self) -> Vec<u8> {
464 let mut r = Vec::with_capacity(self.size_hint());
465
466 Compact(self.len() as u32).encode_to(&mut r);
467 for byte in &self.storage {
468 r.push(*byte);
469 }
470
471 r
472 }
473
474 fn encoded_size(&self) -> usize {
475 // encoding is just compact encoded number of bits and then the bytes to store them all,
476 // rounded to u8 because we mirror the encoding for a BitVec<u8, Lsb0>.
477 let compact_byte_len = Compact(self.len() as u32).encoded_size();
478 compact_byte_len + self.storage.len()
479 }
480}
481
482#[cfg(feature = "scale-info")]
483mod type_info {
484 use scale_info::{build::Fields, Path, Type, TypeDefBitSequence, TypeInfo};
485
486 impl TypeInfo for super::Bits {
487 type Identity = Self;
488
489 fn type_info() -> Type {
490 // Copied from `scale-info`'s bitvec impls; this avoids us needing
491 // to import bitvec but ensures we're compatible in terms of the type def.
492 enum Lsb0 {}
493 impl TypeInfo for Lsb0 {
494 type Identity = Self;
495 fn type_info() -> Type {
496 Type::builder()
497 .path(Path::new("Lsb0", "bitvec::order"))
498 .composite(Fields::unit())
499 }
500 }
501
502 TypeDefBitSequence::new::<u8, Lsb0>().into()
503 }
504 }
505}