archivelib 0.2.0

An implementaton of the Greenleaf ArchiveLib compression/decompression algorithm
Documentation
pub trait ToBits {
  fn to_bits(&self) -> Box<[bool]>;
}
pub trait FromBits {
  fn size() -> usize;
  fn from_bits<I>(_: I) -> Self
  where
    I: IntoIterator<Item = bool>;
}

macro_rules! implBitwise {
  ($type:ty) => {
    impl ToBits for $type {
      fn to_bits(&self) -> Box<[bool]> {
        let size = Self::size();
        let mut v = vec![false; size];
        for i in 0..size {
          v[size - 1 - i] = (self & (1 << i)) != 0;
        }
        v.into_boxed_slice()
      }
    }
    #[allow(clippy::use_self)]
    impl FromBits for $type {
      fn size() -> usize {
        <(Self)>::max_value().count_ones() as usize
      }
      fn from_bits<I>(bits: I) -> Self
      where
        I: IntoIterator<Item = bool>,
      {
        let mut data: Self = 0;
        for bit in bits.into_iter() {
          data = (data << 1) | (if bit { 1 } else { 0 })
        }
        data
      }
    }
  };
}
macro_rules! implBitwiseIter {
  ($type:ty) => {
    #[allow(clippy::use_self)]
    impl<I: ToBits> ToBits for $type {
      fn to_bits(&self) -> Box<[bool]> {
        self
          .iter()
          .flat_map(|v| v.to_bits().into_vec())
          .collect::<Vec<bool>>()
          .into_boxed_slice()
      }
    }
  };
}
implBitwise!(u8);
implBitwise!(u16);
implBitwise!(u32);
implBitwise!(u64);
implBitwise!(u128);
implBitwise!(usize);

impl ToBits for bool {
  fn to_bits(&self) -> Box<[bool]> {
    vec![*self].into_boxed_slice()
  }
}
impl FromBits for bool {
  fn size() -> usize {
    1
  }
  fn from_bits<I>(bits: I) -> Self
  where
    I: IntoIterator<Item = bool>,
  {
    bits.into_iter().next().unwrap_or(false)
  }
}
implBitwiseIter!(Vec<I>);
implBitwiseIter!(&[I]);
implBitwiseIter!([I]);

#[cfg(test)]
mod tests {
  use super::*;

  #[test]
  fn test_to_bits() {
    assert_eq!(
      &0x1_u8.to_bits()[..],
      &[false, false, false, false, false, false, false, true]
    );
    assert_eq!(&0x0_u128.to_bits()[..], &[false; 128][..]);
    assert_eq!(
      &0xff_u8.to_bits()[..],
      &[true, true, true, true, true, true, true, true]
    );
    assert_eq!(
      &0xf0_u8.to_bits()[..],
      &[true, true, true, true, false, false, false, false]
    );
  }
}