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}