scale_bits/scale/
mod.rs

1//! This module exposes some utilities for working with SCALE bit sequences, namely:
2//!
3//! - Encoding: see [`encode_using_format`] and [`encode_using_format_to`].
4//! - Decoding: see [`decode_using_format_from`].
5//! - Talking about obtaining the format of said bit sequences: see the [`mod@format`] module.
6//!
7//! The [`Decoder`] enum can also return the expected number of bytes to be decoded
8//! and the number of bits to be returned without actually decoding them.
9
10mod decode_iter;
11mod encode_iter;
12use alloc::vec::Vec;
13use codec::Error as CodecError;
14
15/// Types to describe the format of some SCALE encoded bits.
16pub mod format {
17	pub use scale_type_resolver::{BitsOrderFormat as OrderFormat, BitsStoreFormat as StoreFormat};
18
19	/// A description of the format used to SCALE encode some bits.
20	#[derive(Clone, Copy, PartialEq, Eq, Debug)]
21	pub struct Format {
22		/// The [`StoreFormat`] defines the size of each chunk that's written (eg u8, u16 etc).
23		pub store: StoreFormat,
24		/// The [`OrderFormat`] determines the order in which we write bits to the store type;
25		/// do we write to the least significant bit first and work up, or write to the most
26		/// significant byte first and work down.
27		pub order: OrderFormat,
28	}
29
30	impl Format {
31		/// Define a new format by providing a store and order.
32		///
33		/// # Example
34		///
35		/// ```rust
36		/// use scale_bits::scale::format::{ Format, StoreFormat, OrderFormat };
37		///
38		/// let format = Format::new(StoreFormat::U8, OrderFormat::Lsb0);
39		/// ```
40		pub fn new(store: StoreFormat, order: OrderFormat) -> Self {
41			Format { store, order }
42		}
43	}
44}
45
46pub use format::Format;
47
48/// This is a convenience wrapper around [`encode_using_format_to`].
49///
50/// # Example
51///
52/// ```rust
53/// use scale_bits::scale::{
54///     encode_using_format,
55///     format::{ Format, StoreFormat, OrderFormat },
56/// };
57///
58/// let bits = vec![true, true, false, true];
59/// let encoded = encode_using_format(
60///     bits.into_iter(),
61///     Format::new(StoreFormat::U8, OrderFormat::Msb0)
62/// );
63/// ```
64pub fn encode_using_format<I: ExactSizeIterator<Item = bool>>(it: I, format: Format) -> Vec<u8> {
65	let mut out = Vec::new();
66	encode_using_format_to(it, format, &mut out);
67	out
68}
69
70/// SCALE encode an iterator of booleans with a known size into a bit sequence using the
71/// given format.
72///
73/// # Example
74///
75/// ```rust
76/// use scale_bits::scale::{
77///     encode_using_format_to,
78///     format::{ Format, StoreFormat, OrderFormat },
79/// };
80///
81/// let bits = vec![true, true, false, true];
82///
83/// let mut encoded = Vec::new();
84/// encode_using_format_to(
85///     bits.into_iter(),
86///     Format::new(StoreFormat::U8, OrderFormat::Msb0),
87///     &mut encoded
88/// );
89/// ```
90pub fn encode_using_format_to<I: ExactSizeIterator<Item = bool>>(
91	it: I,
92	format: Format,
93	out: &mut Vec<u8>,
94) {
95	use encode_iter::*;
96	use format::{OrderFormat, StoreFormat};
97	match (format.store, format.order) {
98		(StoreFormat::U8, OrderFormat::Lsb0) => encode_iter_lsb0_u8(it, out),
99		(StoreFormat::U8, OrderFormat::Msb0) => encode_iter_msb0_u8(it, out),
100		(StoreFormat::U16, OrderFormat::Lsb0) => encode_iter_lsb0_u16(it, out),
101		(StoreFormat::U16, OrderFormat::Msb0) => encode_iter_msb0_u16(it, out),
102		(StoreFormat::U32, OrderFormat::Lsb0) => encode_iter_lsb0_u32(it, out),
103		(StoreFormat::U32, OrderFormat::Msb0) => encode_iter_msb0_u32(it, out),
104		(StoreFormat::U64, OrderFormat::Lsb0) => encode_iter_lsb0_u64(it, out),
105		(StoreFormat::U64, OrderFormat::Msb0) => encode_iter_msb0_u64(it, out),
106	}
107}
108
109/// SCALE decode a bit sequence using the given format, handing back an iterator of booleans.
110///
111/// # Example
112///
113/// ```rust
114/// use scale_bits::scale::{
115///     encode_using_format,
116///     decode_using_format_from,
117///     format::{ Format, StoreFormat, OrderFormat },
118/// };
119///
120/// let bits = vec![true, true, false, true];
121///
122/// // Encode the bits to have something to decode:
123/// let encoded = encode_using_format(
124///     bits.iter().copied(),
125///     Format::new(StoreFormat::U8, OrderFormat::Msb0)
126/// );
127///
128/// // Decode them again.
129/// let decoder = decode_using_format_from(
130///     &encoded,
131///     Format::new(StoreFormat::U8, OrderFormat::Msb0)
132/// ).unwrap();
133/// let new_bits: Result<Vec<bool>,_> = decoder.collect();
134///
135/// assert_eq!(bits, new_bits.unwrap());
136/// ```
137pub fn decode_using_format_from(
138	bytes: &'_ [u8],
139	format: Format,
140) -> Result<Decoder<'_>, CodecError> {
141	use decode_iter::*;
142	use format::{OrderFormat, StoreFormat};
143	let inner = match (format.store, format.order) {
144		(StoreFormat::U8, OrderFormat::Lsb0) => {
145			DecodeInner::DecodeLsb0U8(DecodeLsb0U8::new(bytes)?)
146		}
147		(StoreFormat::U16, OrderFormat::Lsb0) => {
148			DecodeInner::DecodeLsb0U16(DecodeLsb0U16::new(bytes)?)
149		}
150		(StoreFormat::U32, OrderFormat::Lsb0) => {
151			DecodeInner::DecodeLsb0U32(DecodeLsb0U32::new(bytes)?)
152		}
153		(StoreFormat::U64, OrderFormat::Lsb0) => {
154			DecodeInner::DecodeLsb0U64(DecodeLsb0U64::new(bytes)?)
155		}
156		(StoreFormat::U8, OrderFormat::Msb0) => {
157			DecodeInner::DecodeMsb0U8(DecodeMsb0U8::new(bytes)?)
158		}
159		(StoreFormat::U16, OrderFormat::Msb0) => {
160			DecodeInner::DecodeMsb0U16(DecodeMsb0U16::new(bytes)?)
161		}
162		(StoreFormat::U32, OrderFormat::Msb0) => {
163			DecodeInner::DecodeMsb0U32(DecodeMsb0U32::new(bytes)?)
164		}
165		(StoreFormat::U64, OrderFormat::Msb0) => {
166			DecodeInner::DecodeMsb0U64(DecodeMsb0U64::new(bytes)?)
167		}
168	};
169	Ok(Decoder { inner })
170}
171
172/// This is handed back from [`decode_using_format_from`], and can be used to obtain some information about,
173/// or iterate over, the SCALE encoded bit sequence, using the [`Format`] given. Alternately, you can
174/// match on it to retrieve a decoder for the specific format, which may be more efficient.
175///
176/// # Example
177///
178/// ```rust
179/// use scale_bits::scale::{
180///     encode_using_format,
181///     decode_using_format_from,
182///     format::{ Format, StoreFormat, OrderFormat },
183/// };
184///
185/// let bits = vec![true, true, false, true];
186///
187/// // Encode the bits to have something to decode:
188/// let encoded = encode_using_format(
189///     bits.iter().copied(),
190///     Format::new(StoreFormat::U8, OrderFormat::Msb0)
191/// );
192///
193/// // Obtain a decoder given some SCALE encoded bits in some format.
194/// let decoder = decode_using_format_from(
195///     &encoded,
196///     Format::new(StoreFormat::U8, OrderFormat::Msb0)
197/// ).unwrap();
198///
199/// // We can see how many bits are stored:
200/// assert_eq!(decoder.len(), 4);
201///
202/// // We can see how many bytes are used to store them:
203/// assert_eq!(decoder.encoded_size(), encoded.len());
204///
205/// // Decoder is an iterator, so we can iterate and collect the bits back up:
206/// let new_bits: Result<Vec<bool>,_> = decoder.collect();
207/// assert_eq!(bits, new_bits.unwrap());
208/// ```
209#[derive(Clone, Debug)]
210pub struct Decoder<'a> {
211	inner: DecodeInner<'a>,
212}
213
214// [TODO] jsdw: Test performance. Can we scrap the macro stuff to
215// generate the various decode_iter types and just have a single type
216// to avoid needing to match on an enum arm each time we do something?
217// Avoid exposing this so we can do this as a non breaking patch change.
218#[derive(Clone, Debug)]
219enum DecodeInner<'a> {
220	DecodeLsb0U8(decode_iter::DecodeLsb0U8<'a>),
221	DecodeLsb0U16(decode_iter::DecodeLsb0U16<'a>),
222	DecodeLsb0U32(decode_iter::DecodeLsb0U32<'a>),
223	DecodeLsb0U64(decode_iter::DecodeLsb0U64<'a>),
224	DecodeMsb0U8(decode_iter::DecodeMsb0U8<'a>),
225	DecodeMsb0U16(decode_iter::DecodeMsb0U16<'a>),
226	DecodeMsb0U32(decode_iter::DecodeMsb0U32<'a>),
227	DecodeMsb0U64(decode_iter::DecodeMsb0U64<'a>),
228}
229
230macro_rules! decode_iter_arms {
231	($self:ident, $i:ident => $expr:expr) => {{
232		let Self { inner } = $self;
233		match inner {
234			DecodeInner::DecodeLsb0U8($i) => $expr,
235			DecodeInner::DecodeLsb0U16($i) => $expr,
236			DecodeInner::DecodeLsb0U32($i) => $expr,
237			DecodeInner::DecodeLsb0U64($i) => $expr,
238			DecodeInner::DecodeMsb0U8($i) => $expr,
239			DecodeInner::DecodeMsb0U16($i) => $expr,
240			DecodeInner::DecodeMsb0U32($i) => $expr,
241			DecodeInner::DecodeMsb0U64($i) => $expr,
242		}
243	}};
244}
245
246impl<'a> Iterator for Decoder<'a> {
247	type Item = Result<bool, CodecError>;
248	fn next(&mut self) -> Option<Self::Item> {
249		decode_iter_arms!(self, i => i.next())
250	}
251	fn size_hint(&self) -> (usize, Option<usize>) {
252		decode_iter_arms!(self, i => i.size_hint())
253	}
254}
255impl<'a> ExactSizeIterator for Decoder<'a> {}
256
257impl<'a> Decoder<'a> {
258	/// Return the total number of bytes needed to represent the
259	/// SCALE encoded bit sequence we're looking at.
260	pub fn encoded_size(&self) -> usize {
261		decode_iter_arms!(self, i => i.encoded_size())
262	}
263
264	/// Return the remaining bytes.
265	pub fn remaining_bytes(&self) -> &[u8] {
266		decode_iter_arms!(self, i => i.remaining_bytes())
267	}
268}
269
270#[cfg(test)]
271mod test {
272	use super::format::{Format, OrderFormat, StoreFormat};
273	use super::*;
274	use alloc::vec;
275	use bitvec::{
276		order::{BitOrder, Lsb0, Msb0},
277		store::BitStore,
278		vec::BitVec,
279	};
280	use codec::Encode;
281
282	fn assert_iter_matches_bits<S, O>(bits: BitVec<S, O>, format: Format)
283	where
284		S: BitStore,
285		O: BitOrder,
286		BitVec<S, O>: Encode,
287	{
288		// Encode bitvec:
289		let bytes = bits.encode();
290
291		// Turn bitvec to bools:
292		let in_bools: Vec<bool> = bits.clone().into_iter().collect();
293
294		// Decode struct:
295		let decoder = decode_using_format_from(&bytes, format).unwrap();
296
297		// Does decoder know correct size in bytes?
298		assert_eq!(
299			decoder.encoded_size(),
300			bytes.len(),
301			"Wrong size (actual vs expected) for {:?}",
302			bits
303		);
304
305		// Does decoder return the same bools?
306		let out_bools: Result<Vec<bool>, _> = decoder.collect();
307		assert_eq!(in_bools, out_bools.expect("can't collect bools"), "Mismatch for {:?}", bits);
308	}
309
310	fn assert_iter_bits_all_formats(bits: Vec<u8>) {
311		let bits: Vec<bool> = bits
312			.into_iter()
313			.map(|n| match n {
314				0 => false,
315				1 => true,
316				_ => panic!("only 0 or 1 bits allowed"),
317			})
318			.collect();
319
320		let b: BitVec<u8, Lsb0> = bits.iter().collect();
321		let f = Format::new(StoreFormat::U8, OrderFormat::Lsb0);
322		assert_iter_matches_bits(b, f);
323
324		let b: BitVec<u16, Lsb0> = bits.iter().collect();
325		let f = Format::new(StoreFormat::U16, OrderFormat::Lsb0);
326		assert_iter_matches_bits(b, f);
327
328		let b: BitVec<u32, Lsb0> = bits.iter().collect();
329		let f = Format::new(StoreFormat::U32, OrderFormat::Lsb0);
330		assert_iter_matches_bits(b, f);
331
332		let b: BitVec<u64, Lsb0> = bits.iter().collect();
333		let f = Format::new(StoreFormat::U64, OrderFormat::Lsb0);
334		assert_iter_matches_bits(b, f);
335
336		let b: BitVec<u8, Msb0> = bits.iter().collect();
337		let f = Format::new(StoreFormat::U8, OrderFormat::Msb0);
338		assert_iter_matches_bits(b, f);
339
340		let b: BitVec<u16, Msb0> = bits.iter().collect();
341		let f = Format::new(StoreFormat::U16, OrderFormat::Msb0);
342		assert_iter_matches_bits(b, f);
343
344		let b: BitVec<u32, Msb0> = bits.iter().collect();
345		let f = Format::new(StoreFormat::U32, OrderFormat::Msb0);
346		assert_iter_matches_bits(b, f);
347
348		let b: BitVec<u64, Msb0> = bits.iter().collect();
349		let f = Format::new(StoreFormat::U64, OrderFormat::Msb0);
350		assert_iter_matches_bits(b, f);
351	}
352
353	#[test]
354	fn test_iter_bits() {
355		assert_iter_bits_all_formats(vec![]);
356		assert_iter_bits_all_formats(vec![0]);
357		assert_iter_bits_all_formats(vec![0, 1]);
358		assert_iter_bits_all_formats(vec![0, 0, 0]);
359		assert_iter_bits_all_formats(vec![0, 1, 1, 0, 1, 1, 0, 1]);
360		assert_iter_bits_all_formats(vec![0, 1, 1, 0, 1, 1, 0, 1, 0]);
361		assert_iter_bits_all_formats(vec![0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1]);
362		assert_iter_bits_all_formats(vec![0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1]);
363		assert_iter_bits_all_formats(vec![
364			0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1,
365			1, 0, 1, 0,
366		]);
367		assert_iter_bits_all_formats(vec![
368			0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1,
369			1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1,
370			1, 0, 1, 1, 0, 1,
371		]);
372		assert_iter_bits_all_formats(vec![
373			0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1,
374			1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1,
375			1, 0, 1, 1, 0, 1, 0,
376		]);
377	}
378}