use super::PackUnpack;

pub(crate) enum Compression {
    Lz4,
}

impl PackUnpack for Compression {
    fn pack(&self, data: &[u8]) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
        match self {
            Compression::Lz4 => Ok(lz4_compression::prelude::compress(data)),
        }
    }

    fn unpack(&self, data: &[u8]) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
        match self {
            Compression::Lz4 => Ok(lz4_compression::prelude::decompress(data).map_err(
                |e| match e {
                    lz4_compression::decompress::Error::UnexpectedEnd => {
                        "decompress: UnexpectedEnd"
                    }
                    lz4_compression::decompress::Error::InvalidDeduplicationOffset => {
                        "decompress: InvalidDeduplicationOffset"
                    }
                },
            )?),
        }
    }
}

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

    #[test]
    fn check_compression_lz4() {
        fn check_array(data: Vec<u8>) -> bool {
            let c = Compression::Lz4;
            let packed = c.pack(&data).unwrap();
            let unpacked = c.unpack(&packed).unwrap();
            data == unpacked
        }

        quickcheck(check_array as fn(Vec<u8>) -> bool);
    }
}
