#[cfg(feature = "alloc")]
extern crate alloc as core_alloc;
#[cfg(feature = "alloc")]
use core_alloc::vec::Vec;
use crate::{str::StrBitIter, BitIter, IntoBitIter, Lsb0, Msb0};
pub trait BitOrder: sealed::Sealed + Clone + Copy + Send + Sync + 'static {}
mod sealed {
pub trait Sealed {}
impl Sealed for super::Lsb0 {}
impl Sealed for super::Msb0 {}
}
pub trait BitLength {
const BITS: usize;
}
impl<T: ?Sized> BitLength for &T
where
T: BitLength,
{
const BITS: usize = T::BITS;
}
pub trait GetBit<O>
where
O: BitOrder,
{
fn get_bit(&self, index: usize) -> bool;
}
impl<T: ?Sized, O> GetBit<O> for &T
where
T: GetBit<O>,
O: BitOrder,
{
fn get_bit(&self, index: usize) -> bool {
T::get_bit(*self, index)
}
}
pub trait SetBit<O>
where
O: BitOrder,
{
fn set_bit(&mut self, index: usize, value: bool);
}
impl<T: ?Sized, O> SetBit<O> for &mut T
where
T: SetBit<O>,
O: BitOrder,
{
fn set_bit(&mut self, index: usize, value: bool) {
T::set_bit(*self, index, value)
}
}
pub trait BitIterable: GetBit<Lsb0> + GetBit<Msb0> + BitLength {}
impl<T: ?Sized> BitIterable for &T where T: BitIterable {}
pub trait FromBitIterator {
fn from_lsb0_iter(iter: impl IntoIterator<Item = bool>) -> Self;
fn from_msb0_iter(iter: impl IntoIterator<Item = bool>) -> Self;
}
macro_rules! impl_from_bit_iterator_tuple {
($($T:ident),+ $(,)?) => {
impl<$($T),+> FromBitIterator for ($($T),+ ,)
where
$($T: FromBitIterator + BitLength),+
{
fn from_lsb0_iter(iter: impl IntoIterator<Item = bool>) -> Self {
let mut iter = iter.into_iter();
(
$($T::from_lsb0_iter(iter.by_ref())),+ ,
)
}
fn from_msb0_iter(iter: impl IntoIterator<Item = bool>) -> Self {
let mut iter = iter.into_iter();
(
$($T::from_msb0_iter(iter.by_ref())),+ ,
)
}
}
};
}
impl_from_bit_iterator_tuple!(T1);
impl_from_bit_iterator_tuple!(T1, T2);
impl_from_bit_iterator_tuple!(T1, T2, T3);
impl_from_bit_iterator_tuple!(T1, T2, T3, T4);
impl_from_bit_iterator_tuple!(T1, T2, T3, T4, T5);
impl_from_bit_iterator_tuple!(T1, T2, T3, T4, T5, T6);
impl_from_bit_iterator_tuple!(T1, T2, T3, T4, T5, T6, T7);
impl_from_bit_iterator_tuple!(T1, T2, T3, T4, T5, T6, T7, T8);
impl_from_bit_iterator_tuple!(T1, T2, T3, T4, T5, T6, T7, T8, T9);
impl_from_bit_iterator_tuple!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);
impl_from_bit_iterator_tuple!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);
impl_from_bit_iterator_tuple!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12);
pub trait ToBits<'a> {
type IterLsb0: Iterator<Item = bool> + 'a;
type IterMsb0: Iterator<Item = bool> + 'a;
fn iter_lsb0(&'a self) -> Self::IterLsb0;
#[cfg(feature = "alloc")]
fn to_lsb0_vec(&'a self) -> Vec<bool> {
self.iter_lsb0().collect()
}
fn iter_msb0(&'a self) -> Self::IterMsb0;
#[cfg(feature = "alloc")]
fn to_msb0_vec(&'a self) -> Vec<bool> {
self.iter_msb0().collect()
}
}
impl<'a, T> ToBits<'a> for T
where
&'a T: GetBit<Lsb0> + GetBit<Msb0> + BitLength + 'a,
{
type IterLsb0 = BitIter<&'a T, Lsb0>;
type IterMsb0 = BitIter<&'a T, Msb0>;
fn iter_lsb0(&'a self) -> Self::IterLsb0 {
BitIter::from(self)
}
fn iter_msb0(&'a self) -> Self::IterMsb0 {
BitIter::from(self)
}
}
pub trait IntoBits {
type IterLsb0: Iterator<Item = bool>;
type IterMsb0: Iterator<Item = bool>;
fn into_iter_lsb0(self) -> Self::IterLsb0;
#[cfg(feature = "alloc")]
fn into_lsb0_vec(self) -> Vec<bool>
where
Self: Sized,
{
self.into_iter_lsb0().collect()
}
fn into_iter_msb0(self) -> Self::IterMsb0;
#[cfg(feature = "alloc")]
fn into_msb0_vec(self) -> Vec<bool>
where
Self: Sized,
{
self.into_iter_msb0().collect()
}
}
impl<T> IntoBits for T
where
T: GetBit<Lsb0> + GetBit<Msb0> + BitLength,
{
type IterLsb0 = BitIter<T, Lsb0>;
type IterMsb0 = BitIter<T, Msb0>;
fn into_iter_lsb0(self) -> Self::IterLsb0 {
BitIter::from(self)
}
fn into_iter_msb0(self) -> Self::IterMsb0 {
BitIter::from(self)
}
}
pub trait IntoBitIterator {
type IterLsb0: Iterator<Item = bool>;
type IterMsb0: Iterator<Item = bool>;
fn into_iter_lsb0(self) -> Self::IterLsb0;
#[cfg(feature = "alloc")]
fn into_lsb0_vec(self) -> Vec<bool>
where
Self: Sized,
{
self.into_iter_lsb0().collect()
}
fn into_iter_msb0(self) -> Self::IterMsb0;
#[cfg(feature = "alloc")]
fn into_msb0_vec(self) -> Vec<bool>
where
Self: Sized,
{
self.into_iter_msb0().collect()
}
}
impl<T> IntoBitIterator for T
where
T: IntoIterator,
T::Item: GetBit<Lsb0> + GetBit<Msb0> + BitLength,
{
type IterLsb0 = IntoBitIter<T::IntoIter, Lsb0>;
type IterMsb0 = IntoBitIter<T::IntoIter, Msb0>;
fn into_iter_lsb0(self) -> Self::IterLsb0 {
IntoBitIter::from(self.into_iter())
}
fn into_iter_msb0(self) -> Self::IterMsb0 {
IntoBitIter::from(self.into_iter())
}
}
pub trait StrToBits<'a> {
fn iter_bits(&'a self) -> StrBitIter<'a>;
#[cfg(feature = "alloc")]
fn to_bit_vec(&'a self) -> Vec<bool> {
self.iter_bits().collect()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_from_bit_iterator_tuple() {
let a = 42u8;
let b = 69u16;
let (x, y): (u8, u16) = FromBitIterator::from_lsb0_iter(a.iter_lsb0().chain(b.iter_lsb0()));
assert_eq!(x, 42);
assert_eq!(y, 69);
let (x, y): (u8, u16) = FromBitIterator::from_msb0_iter(a.iter_msb0().chain(b.iter_msb0()));
assert_eq!(x, 42);
assert_eq!(y, 69);
}
}