ldeflate 0.1.3

Pure Rust parallel DEFLATE/zlib compressor — the write side of linflate. Two-queue gatling scheduling: coalesce small objects, split large streams at full-flush boundaries.
Documentation
//! **Appliance-eligibility guard.** `ldeflate` must pull no C, no cmake, no
//! bindgen and no `*-sys` crate, because anything that does is disqualified
//! from the appliance (this is exactly why OpenZL is a problem elsewhere in the
//! tree, and why znippy's C/cmake/network build requirement is logged as a
//! blocker in gunnar's `P-006`).
//!
//! The risk this guards is not the direct dependency — that is one visible line
//! in `Cargo.toml`. It is a **transitive** one: `flate2` will happily pull
//! `libz-sys` (C + cmake, via `zlib-ng-compat`) or `libz-ng-sys` if a feature is
//! added anywhere in the workspace and unification reaches us. So the check is
//! run against the resolved dependency graph, not the manifest.

use std::process::Command;

fn tree(pkg: &str) -> Option<String> {
    let out = Command::new("cargo")
        .args(["tree", "--offline", "-p", pkg, "-e", "normal,build"])
        .current_dir(env!("CARGO_MANIFEST_DIR"))
        .output()
        .ok()?;
    if !out.status.success() {
        return None;
    }
    Some(String::from_utf8_lossy(&out.stdout).into_owned())
}

/// Crate-name fragments that mean "a C toolchain, cmake, or a native library is
/// required to build this".
const C_MARKERS: &[&str] = &[
    "libz-sys",
    "libz-ng-sys",
    "cloudflare-zlib-sys",
    "zstd-sys",
    "bzip2-sys",
    "openssl-sys",
    "cmake",
    "bindgen",
];

/// Does `line` name a package whose name matches a C marker? Matches on the
/// package-name token only, so a path containing e.g. "cmake" in a directory
/// name cannot false-positive.
fn c_hit(line: &str) -> Option<String> {
    let name = line
        .trim_start_matches(['├', '─', '│', '└', ' ', '[', ']'])
        .split_whitespace()
        .next()
        .unwrap_or("");
    if name == "cc" || C_MARKERS.iter().any(|m| name == *m) {
        return Some(name.to_string());
    }
    None
}

#[test]
fn ldeflate_pulls_no_c_no_cmake_no_sys_crate() {
    let Some(t) = tree("ldeflate") else {
        eprintln!("SKIP no-C guard: `cargo tree --offline` unavailable here");
        return;
    };
    let hits: Vec<String> = t.lines().filter_map(c_hit).collect();
    assert!(
        hits.is_empty(),
        "ldeflate's resolved dependency graph pulls a C/cmake/sys crate: {hits:?}\n\
         This disqualifies it from the appliance. The usual cause is a `flate2` \
         feature (zlib / zlib-ng / zlib-ng-compat / cloudflare_zlib) reaching us \
         through feature unification. `ldeflate` must stay on \
         `default-features = false, features = [\"zlib-rs\"]`.\n\nfull tree:\n{t}"
    );
}

/// **RED-first control.** The marker scan above is worthless if it cannot
/// actually detect a C dependency. `zstd-sys-rs` in this same workspace vendors
/// libzstd and builds it with `cc` + `bindgen` — so the *same* scan run against
/// it must fire. If this test ever goes quiet, the guard above is blind.
#[test]
fn the_c_marker_scan_actually_fires_on_a_crate_that_has_c() {
    let Some(t) = tree("zstd-sys-rs") else {
        eprintln!("SKIP no-C guard control: `cargo tree --offline` unavailable here");
        return;
    };
    let hits: Vec<String> = t.lines().filter_map(c_hit).collect();
    assert!(
        !hits.is_empty(),
        "the C-marker scan found NOTHING in zstd-sys-rs, which demonstrably \
         compiles ~25 vendored .c files via `cc` and generates bindings with \
         `bindgen`. The scan is broken, so the ldeflate guard above proves \
         nothing.\n\nfull tree:\n{t}"
    );
    eprintln!("control OK — scan fired on zstd-sys-rs: {hits:?}");
}

/// The crate must own no build script and no native sources of its own.
#[test]
fn ldeflate_has_no_build_script_and_no_native_sources() {
    let root = std::path::Path::new(env!("CARGO_MANIFEST_DIR"));
    assert!(
        !root.join("build.rs").exists(),
        "ldeflate must have no build.rs"
    );
    let mut stack = vec![root.to_path_buf()];
    while let Some(d) = stack.pop() {
        let Ok(rd) = std::fs::read_dir(&d) else {
            continue;
        };
        for e in rd.flatten() {
            let p = e.path();
            if p.is_dir() {
                if p.file_name().is_some_and(|n| n == "target") {
                    continue;
                }
                stack.push(p);
                continue;
            }
            let ext = p.extension().and_then(|x| x.to_str()).unwrap_or("");
            assert!(
                !matches!(ext, "c" | "h" | "cc" | "cpp" | "S"),
                "ldeflate carries a native source file: {}",
                p.display()
            );
            assert!(
                p.file_name().is_none_or(|n| n != "CMakeLists.txt"),
                "ldeflate carries a CMakeLists.txt: {}",
                p.display()
            );
        }
    }
}