xpress_rs 0.2.0

Xpress implementation in Rust
Documentation
use std::error::Error;
use std::fs;
use std::io::Read;
use std::time::Instant;
use xpress_rs::lz77::{LZ77Compressor, LZ77Decompressor};

fn test_compress_lz77(data_to_compress: Vec<u8>) -> Result<Vec<u8>, Box<dyn Error>> {
    // init the Compressor
    let compressor = LZ77Compressor::new(data_to_compress);

    // compress the data
    let result: Result<Vec<u8>, Box<dyn Error>> = compressor.compress();

    // check if the compression is successful
    match result {
        Ok(compressed_data) => Ok(compressed_data),
        Err(e) => Err(e),
    }
}

fn test_lz77_decompression(data_to_decompress: Vec<u8>) -> Result<Vec<u8>, Box<dyn Error>> {
    // init the Decompressor
    let decompressor = LZ77Decompressor::new(data_to_decompress);

    // decompress the data
    let result: Result<Vec<u8>, Box<dyn Error>> = decompressor.decompress();

    // check if the decompression is successful
    match result {
        Ok(decompressed_data) => Ok(decompressed_data),
        Err(e) => Err(e),
    }
}

#[test]
fn testlz77() {
    #[cfg(feature = "logging")]
    {
        use env_logger::Env;
        use log::{info, LevelFilter};
        env_logger::Builder::new()
            .filter(None, LevelFilter::Info)
            .init();
    }
    let data_to_compress: Vec<u8> = b"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.".to_vec();
    let data_to_decompress: Vec<u8> = test_compress_lz77(data_to_compress.clone())
        .map_err(|e| format!("Error: {}", e))
        .unwrap();
    let result = test_lz77_decompression(data_to_decompress)
        .map_err(|e| format!("Error: {}", e))
        .unwrap();
    assert_eq!(result, data_to_compress);
}

#[test]
fn bench_lz77() {
    //let mut data = fs::File::open("small.txt").unwrap();
    //let mut data = fs::File::open("medium.txt").unwrap();
    let mut data = fs::File::open("tests/large.txt").unwrap();
    let mut data_content = Vec::new();
    data.read_to_end(&mut data_content).unwrap();

    let time = Instant::now();
    let compressed_data = test_compress_lz77(data_content.clone()).unwrap();
    println!(
        "Crate : time to compress: {}s",
        time.elapsed().as_secs_f64()
    );
    println!(
        "Crate : compress ratio: {}%",
        compressed_data.len() as f64 / data_content.len() as f64 * 100.0
    );

    let time = Instant::now();
    let _ = test_lz77_decompression(compressed_data.clone()).unwrap();
    println!(
        "Crate : time to decompress: {}s",
        time.elapsed().as_secs_f64()
    );
}

#[cfg(windows)]
mod windows_only {
    use std::fs;
    use std::io::Read;
    use windows::Win32::Foundation::{GetLastError, BOOL};
    #[cfg(target_os = "windows")]
    use windows::Win32::Storage::Compression::{
        Compress, CreateCompressor, COMPRESSOR_HANDLE, COMPRESS_ALGORITHM_XPRESS,
    };

    #[test]
    fn test_windows_api() {
        unsafe {
            let instant = std::time::Instant::now();
            let mut compressor_handle: isize = 0;
            let result = CreateCompressor(COMPRESS_ALGORITHM_XPRESS, None, &mut compressor_handle);
            if result == BOOL(0) {
                println!("Error: {:?}", GetLastError());
            }

            let mut data = fs::File::open("tests/large.txt").unwrap();
            let mut data_content = Vec::new();
            data.read_to_end(&mut data_content).unwrap();

            let mut compressed_data = vec![0u8; data_content.len()];
            let mut compressed_data_len: usize = 0;

            let compressor_handle = COMPRESSOR_HANDLE(compressor_handle);
            let result = Compress(
                compressor_handle,
                Some(data_content.as_ptr() as *const _),
                data_content.len(),
                Some(compressed_data.as_mut_ptr() as *mut _),
                compressed_data.len(),
                &mut compressed_data_len,
            );
            if result == BOOL(0) {
                println!("Error: {:?}", GetLastError());
            } else {
                println!(
                    "Winapi : time to compress: {}s",
                    instant.elapsed().as_secs_f64()
                );
                println!(
                    "Winapi : compress ratio: {}%",
                    (compressed_data_len as f64 / data_content.len() as f64) * 100.0
                );
            }
        }
    }
}