use comprezable::Comprezable;
use error::DecompressError;
pub mod error;
pub mod comprezable;
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum Compressed {
Binaries(Vec<u8>),
Bytes(Vec<u8>),
}
impl Compressed {
pub fn new() -> Self {
Self::Binaries(vec![])
}
pub fn to_bytes(&self) -> Vec<u8> {
match self {
Self::Binaries(binaries) => {
let mut binaries = binaries.clone();
while binaries.len() % 8 != 0 {
binaries.push(0);
}
let chunked_binaries = binaries.chunks(8).collect::<Vec<&[u8]>>();
let mut bytes = vec![];
for chunk in chunked_binaries {
bytes.push(to_byte(chunk));
}
bytes
},
Self::Bytes(bytes) => {
bytes.to_vec()
},
}
}
pub fn to_binaries(&self) -> Vec<u8> {
match self {
Self::Binaries(binaries) => {
binaries.to_vec()
},
Self::Bytes(bytes) => {
to_binary(bytes.to_vec())
}
}
}
pub fn extend_to_res(self, res: &mut Vec<u8>) {
let binaries = self.to_binaries();
res.extend(binaries);
}
pub fn combine(self, other: Compressed) -> Self {
let mut binaries = self.to_binaries();
let other_binaries = other.to_binaries();
binaries.extend(other_binaries);
Self::Binaries(binaries)
}
pub fn from_bytes(bytes: Vec<u8>) -> Self {
Compressed::Bytes(bytes)
}
pub fn from_binaries(binaries: &[u8]) -> Self {
Compressed::Binaries(binaries.to_vec())
}
}
#[derive(Debug, Clone)]
pub enum BinaryChunk {
Single(usize),
Nested(Vec<BinaryChunk>),
Delimeter,
}
impl BinaryChunk {
pub fn flatten(&self) -> Vec<usize> {
match self {
Self::Single(size) => {
vec![*size]
},
Self::Nested(sizes) => {
sizes.iter().fold(vec![], |mut acc, chunk| { acc.extend(chunk.flatten()); acc})
},
Self::Delimeter => {
vec![0]
}
}
}
pub fn decompress<T: Comprezable>(&self, compressed: &mut Vec<u8>) -> Result<T, DecompressError> {
match self {
BinaryChunk::Single(size) => {
T::decompress_from_binaries(compressed, Some(*size))
},
BinaryChunk::Nested(_) => {
T::decompress_from_binaries(compressed, None)
},
BinaryChunk::Delimeter => {
T::decompress_from_binaries(compressed, None)
}
}
}
}
fn to_byte(bits: &[u8]) -> u8 {
bits.iter()
.fold(0, |result, &bit| {
(result << 1) ^ bit
})
}
fn to_binary(bytes: Vec<u8>) -> Vec<u8> {
let mut binaries = vec![];
for byte in bytes {
let mut a = format!("{:b}", byte);
while a.len() < 8 {
a.insert(0, '0');
}
let temp_binaries = a.chars().map(|c| c.to_digit(2).unwrap() as u8).collect::<Vec<u8>>();
binaries.extend(temp_binaries);
}
binaries
}