mod decode_iter;
mod encode_iter;
use alloc::vec::Vec;
use codec::Error as CodecError;
pub mod format;
pub use format::Format;
pub fn encode_using_format<I: ExactSizeIterator<Item = bool>>(it: I, format: Format) -> Vec<u8> {
let mut out = Vec::new();
encode_using_format_to(it, format, &mut out);
out
}
pub fn encode_using_format_to<I: ExactSizeIterator<Item = bool>>(
it: I,
format: Format,
out: &mut Vec<u8>,
) {
use encode_iter::*;
use format::{OrderFormat, StoreFormat};
match (format.store, format.order) {
(StoreFormat::U8, OrderFormat::Lsb0) => encode_iter_lsb0_u8(it, out),
(StoreFormat::U8, OrderFormat::Msb0) => encode_iter_msb0_u8(it, out),
(StoreFormat::U16, OrderFormat::Lsb0) => encode_iter_lsb0_u16(it, out),
(StoreFormat::U16, OrderFormat::Msb0) => encode_iter_msb0_u16(it, out),
(StoreFormat::U32, OrderFormat::Lsb0) => encode_iter_lsb0_u32(it, out),
(StoreFormat::U32, OrderFormat::Msb0) => encode_iter_msb0_u32(it, out),
(StoreFormat::U64, OrderFormat::Lsb0) => encode_iter_lsb0_u64(it, out),
(StoreFormat::U64, OrderFormat::Msb0) => encode_iter_msb0_u64(it, out),
}
}
pub fn decode_using_format_from(
bytes: &'_ [u8],
format: Format,
) -> Result<Decoder<'_>, CodecError> {
use decode_iter::*;
use format::{OrderFormat, StoreFormat};
let inner = match (format.store, format.order) {
(StoreFormat::U8, OrderFormat::Lsb0) => {
DecodeInner::DecodeLsb0U8(DecodeLsb0U8::new(bytes)?)
}
(StoreFormat::U16, OrderFormat::Lsb0) => {
DecodeInner::DecodeLsb0U16(DecodeLsb0U16::new(bytes)?)
}
(StoreFormat::U32, OrderFormat::Lsb0) => {
DecodeInner::DecodeLsb0U32(DecodeLsb0U32::new(bytes)?)
}
(StoreFormat::U64, OrderFormat::Lsb0) => {
DecodeInner::DecodeLsb0U64(DecodeLsb0U64::new(bytes)?)
}
(StoreFormat::U8, OrderFormat::Msb0) => {
DecodeInner::DecodeMsb0U8(DecodeMsb0U8::new(bytes)?)
}
(StoreFormat::U16, OrderFormat::Msb0) => {
DecodeInner::DecodeMsb0U16(DecodeMsb0U16::new(bytes)?)
}
(StoreFormat::U32, OrderFormat::Msb0) => {
DecodeInner::DecodeMsb0U32(DecodeMsb0U32::new(bytes)?)
}
(StoreFormat::U64, OrderFormat::Msb0) => {
DecodeInner::DecodeMsb0U64(DecodeMsb0U64::new(bytes)?)
}
};
Ok(Decoder { inner })
}
#[derive(Clone, Debug)]
pub struct Decoder<'a> {
inner: DecodeInner<'a>,
}
#[derive(Clone, Debug)]
enum DecodeInner<'a> {
DecodeLsb0U8(decode_iter::DecodeLsb0U8<'a>),
DecodeLsb0U16(decode_iter::DecodeLsb0U16<'a>),
DecodeLsb0U32(decode_iter::DecodeLsb0U32<'a>),
DecodeLsb0U64(decode_iter::DecodeLsb0U64<'a>),
DecodeMsb0U8(decode_iter::DecodeMsb0U8<'a>),
DecodeMsb0U16(decode_iter::DecodeMsb0U16<'a>),
DecodeMsb0U32(decode_iter::DecodeMsb0U32<'a>),
DecodeMsb0U64(decode_iter::DecodeMsb0U64<'a>),
}
macro_rules! decode_iter_arms {
($self:ident, $i:ident => $expr:expr) => {{
let Self { inner } = $self;
match inner {
DecodeInner::DecodeLsb0U8($i) => $expr,
DecodeInner::DecodeLsb0U16($i) => $expr,
DecodeInner::DecodeLsb0U32($i) => $expr,
DecodeInner::DecodeLsb0U64($i) => $expr,
DecodeInner::DecodeMsb0U8($i) => $expr,
DecodeInner::DecodeMsb0U16($i) => $expr,
DecodeInner::DecodeMsb0U32($i) => $expr,
DecodeInner::DecodeMsb0U64($i) => $expr,
}
}};
}
impl<'a> Iterator for Decoder<'a> {
type Item = Result<bool, CodecError>;
fn next(&mut self) -> Option<Self::Item> {
decode_iter_arms!(self, i => i.next())
}
fn size_hint(&self) -> (usize, Option<usize>) {
decode_iter_arms!(self, i => i.size_hint())
}
}
impl<'a> ExactSizeIterator for Decoder<'a> {}
impl<'a> Decoder<'a> {
pub fn encoded_size(&self) -> usize {
decode_iter_arms!(self, i => i.encoded_size())
}
pub fn remaining_bytes(&self) -> &[u8] {
decode_iter_arms!(self, i => i.remaining_bytes())
}
}
#[cfg(test)]
mod test {
use super::format::{Format, OrderFormat, StoreFormat};
use super::*;
use alloc::vec;
use bitvec::{
order::{BitOrder, Lsb0, Msb0},
store::BitStore,
vec::BitVec,
};
use codec::Encode;
fn assert_iter_matches_bits<S, O>(bits: BitVec<S, O>, format: Format)
where
S: BitStore,
O: BitOrder,
BitVec<S, O>: Encode,
{
let bytes = bits.encode();
let in_bools: Vec<bool> = bits.clone().into_iter().collect();
let decoder = decode_using_format_from(&bytes, format).unwrap();
assert_eq!(
decoder.encoded_size(),
bytes.len(),
"Wrong size (actual vs expected) for {:?}",
bits
);
let out_bools: Result<Vec<bool>, _> = decoder.collect();
assert_eq!(in_bools, out_bools.expect("can't collect bools"), "Mismatch for {:?}", bits);
}
fn assert_iter_bits_all_formats(bits: Vec<u8>) {
let bits: Vec<bool> = bits
.into_iter()
.map(|n| match n {
0 => false,
1 => true,
_ => panic!("only 0 or 1 bits allowed"),
})
.collect();
let b: BitVec<u8, Lsb0> = bits.iter().collect();
let f = Format::new(StoreFormat::U8, OrderFormat::Lsb0);
assert_iter_matches_bits(b, f);
let b: BitVec<u16, Lsb0> = bits.iter().collect();
let f = Format::new(StoreFormat::U16, OrderFormat::Lsb0);
assert_iter_matches_bits(b, f);
let b: BitVec<u32, Lsb0> = bits.iter().collect();
let f = Format::new(StoreFormat::U32, OrderFormat::Lsb0);
assert_iter_matches_bits(b, f);
let b: BitVec<u64, Lsb0> = bits.iter().collect();
let f = Format::new(StoreFormat::U64, OrderFormat::Lsb0);
assert_iter_matches_bits(b, f);
let b: BitVec<u8, Msb0> = bits.iter().collect();
let f = Format::new(StoreFormat::U8, OrderFormat::Msb0);
assert_iter_matches_bits(b, f);
let b: BitVec<u16, Msb0> = bits.iter().collect();
let f = Format::new(StoreFormat::U16, OrderFormat::Msb0);
assert_iter_matches_bits(b, f);
let b: BitVec<u32, Msb0> = bits.iter().collect();
let f = Format::new(StoreFormat::U32, OrderFormat::Msb0);
assert_iter_matches_bits(b, f);
let b: BitVec<u64, Msb0> = bits.iter().collect();
let f = Format::new(StoreFormat::U64, OrderFormat::Msb0);
assert_iter_matches_bits(b, f);
}
#[test]
fn test_iter_bits() {
assert_iter_bits_all_formats(vec![]);
assert_iter_bits_all_formats(vec![0]);
assert_iter_bits_all_formats(vec![0, 1]);
assert_iter_bits_all_formats(vec![0, 0, 0]);
assert_iter_bits_all_formats(vec![0, 1, 1, 0, 1, 1, 0, 1]);
assert_iter_bits_all_formats(vec![0, 1, 1, 0, 1, 1, 0, 1, 0]);
assert_iter_bits_all_formats(vec![0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1]);
assert_iter_bits_all_formats(vec![0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1]);
assert_iter_bits_all_formats(vec![
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,
1, 0, 1, 0,
]);
assert_iter_bits_all_formats(vec![
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,
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,
1, 0, 1, 1, 0, 1,
]);
assert_iter_bits_all_formats(vec![
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,
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,
1, 0, 1, 1, 0, 1, 0,
]);
}
}