lazippy 0.0.1

Pure-Rust LZMA (Lempel-Ziv-Markov chain Algorithm), part of the 8z umbrella
Documentation
//! Test-vector loader for committed LZMA test vectors in `tests/vectors/`.
//!
//! Each vector is a pair of files:
//! - `<name>.raw`  — the original (uncompressed) bytes
//! - `<name>.lzma` — the LZMA-compressed bytes produced by the reference SDK

use std::path::PathBuf;

/// Returns the path to the `tests/vectors/` directory.
pub fn vectors_dir() -> PathBuf {
    PathBuf::from(env!("CARGO_MANIFEST_DIR"))
        .join("tests")
        .join("vectors")
}

/// A single raw↔lzma vector pair.
#[allow(dead_code)] // fields will be read once test vectors are committed
pub struct Vector {
    pub name: String,
    pub raw: Vec<u8>,
    pub lzma: Vec<u8>,
}

/// Load all vectors from `tests/vectors/`. Returns an empty list if the
/// directory is empty (expected during initial scaffolding).
pub fn load_all() -> Vec<Vector> {
    let dir = vectors_dir();
    if !dir.exists() {
        return vec![];
    }

    let mut names: Vec<String> = std::fs::read_dir(&dir)
        .expect("read tests/vectors/")
        .filter_map(|e| e.ok())
        .filter_map(|e| {
            let p = e.path();
            if p.extension().and_then(|s| s.to_str()) == Some("raw") {
                p.file_stem().and_then(|s| s.to_str()).map(|s| s.to_owned())
            } else {
                None
            }
        })
        .collect();
    names.sort();

    names
        .into_iter()
        .filter_map(|name| {
            let raw_path = dir.join(format!("{name}.raw"));
            let lzma_path = dir.join(format!("{name}.lzma"));
            if raw_path.exists() && lzma_path.exists() {
                Some(Vector {
                    name: name.clone(),
                    raw: std::fs::read(&raw_path)
                        .unwrap_or_else(|_| panic!("read {}", raw_path.display())),
                    lzma: std::fs::read(&lzma_path)
                        .unwrap_or_else(|_| panic!("read {}", lzma_path.display())),
                })
            } else {
                None
            }
        })
        .collect()
}

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

    #[test]
    fn load_all_does_not_panic() {
        // During scaffolding there are no vectors, so load_all() returns [].
        let vecs = load_all();
        // When vectors are added this count will be > 0.
        let _ = vecs.len();
    }
}