diff --git a/src/rle.rs b/src/rle.rs index 63d6b68..655ed6d 100644 --- a/src/rle.rs +++ b/src/rle.rs @@ -1,3 +1,37 @@ +use std::io::Read; + +use bitvec::{slice::BitSlice, vec::BitVec}; + +use crate::CompressionScheme; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct Rle; + +impl CompressionScheme for Rle { + type Header = (); + + fn encode(src: &[u8], buf: &mut BitVec) -> Self::Header { + for Run { count, byte } in Encoder::new(src) { + // TODO: surely this can be expressed better + buf.extend_from_bitslice(BitSlice::::from_slice(&[count, byte])); + } + } + + fn decode(src: &BitSlice, (): &Self::Header, buf: &mut Vec) { + #[allow(clippy::unbuffered_bytes)] + let mut bytes = src.bytes(); + while let (Some(Ok(count)), Some(Ok(byte))) = (bytes.next(), bytes.next()) { + for _ in 0..count { + buf.push(byte); + } + } + } + + fn header_size((): &Self::Header) -> usize { + 0 + } +} + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct Run { pub count: u8, diff --git a/src/test.rs b/src/test.rs index ecf36d2..4777530 100644 --- a/src/test.rs +++ b/src/test.rs @@ -4,6 +4,12 @@ use crate::{CompressionScheme, Freq, Rle}; #[allow(clippy::needless_pass_by_value)] #[quickcheck] -fn freq_roundtrip(src: Vec) -> bool { +fn roundtrip_freq(src: Vec) -> bool { Freq::idempotent_on(&src) } + +#[allow(clippy::needless_pass_by_value)] +#[quickcheck] +fn roundtrip_rle(src: Vec) -> bool { + Rle::idempotent_on(&src) +}