mod r#as;
mod writer;
pub use self::{r#as::*, writer::*};
use std::{rc::Rc, sync::Arc};
use bitvec::{order::Msb0, slice::BitSlice, vec::BitVec};
use impl_tools::autoimpl;
use crate::{AsBytes, ResultExt, StringError};
#[autoimpl(for<S: trait + ?Sized> &S, &mut S, Box<S>, Rc<S>, Arc<S>)]
pub trait BitPack {
fn pack<W>(&self, writer: W) -> Result<(), W::Error>
where
W: BitWriter;
}
#[inline]
pub fn pack<T>(value: T) -> Result<BitVec<u8, Msb0>, StringError>
where
T: BitPack,
{
let mut writer = BitVec::new();
writer.pack(value)?;
Ok(writer)
}
impl BitPack for () {
#[inline]
fn pack<W>(&self, _writer: W) -> Result<(), W::Error>
where
W: BitWriter,
{
Ok(())
}
}
impl BitPack for bool {
#[inline]
fn pack<W>(&self, mut writer: W) -> Result<(), W::Error>
where
W: BitWriter,
{
writer.write_bit(*self).map_err(Into::into)
}
}
impl<T> BitPack for [T]
where
T: BitPack,
{
#[inline]
fn pack<W>(&self, mut writer: W) -> Result<(), W::Error>
where
W: BitWriter,
{
writer.pack_many(self)?;
Ok(())
}
}
impl<T, const N: usize> BitPack for [T; N]
where
T: BitPack,
{
#[inline]
fn pack<W>(&self, writer: W) -> Result<(), W::Error>
where
W: BitWriter,
{
self.as_slice().pack(writer)
}
}
macro_rules! impl_bit_serialize_for_tuple {
($($n:tt:$t:ident),+) => {
impl<$($t),+> BitPack for ($($t,)+)
where $(
$t: BitPack,
)+
{
#[inline]
fn pack<W>(&self, mut writer: W) -> Result<(), W::Error>
where
W: BitWriter,
{
$(self.$n.pack(&mut writer).context(concat!(".", stringify!($n)))?;)+
Ok(())
}
}
};
}
impl_bit_serialize_for_tuple!(0:T0);
impl_bit_serialize_for_tuple!(0:T0,1:T1);
impl_bit_serialize_for_tuple!(0:T0,1:T1,2:T2);
impl_bit_serialize_for_tuple!(0:T0,1:T1,2:T2,3:T3);
impl_bit_serialize_for_tuple!(0:T0,1:T1,2:T2,3:T3,4:T4);
impl_bit_serialize_for_tuple!(0:T0,1:T1,2:T2,3:T3,4:T4,5:T5);
impl_bit_serialize_for_tuple!(0:T0,1:T1,2:T2,3:T3,4:T4,5:T5,6:T6);
impl_bit_serialize_for_tuple!(0:T0,1:T1,2:T2,3:T3,4:T4,5:T5,6:T6,7:T7);
impl_bit_serialize_for_tuple!(0:T0,1:T1,2:T2,3:T3,4:T4,5:T5,6:T6,7:T7,8:T8);
impl_bit_serialize_for_tuple!(0:T0,1:T1,2:T2,3:T3,4:T4,5:T5,6:T6,7:T7,8:T8,9:T9);
impl<'a> BitPack for &'a BitSlice<u8, Msb0> {
#[inline]
fn pack<W>(&self, mut writer: W) -> Result<(), W::Error>
where
W: BitWriter,
{
writer.write_bitslice(self)
}
}
impl BitPack for str {
#[inline]
fn pack<W>(&self, mut writer: W) -> Result<(), W::Error>
where
W: BitWriter,
{
writer.pack_as::<_, AsBytes>(self)?;
Ok(())
}
}