hdf5-bitshuffle 0.9.1

HDF5 bitshuffle plugin for Rust
Documentation
use std::fs::File;
use std::io::Write;
use std::path::PathBuf;
use std::{env, fs};

static CMAKE_SEPARATOR: &[u8] = b"\n";

fn main() {
    let out = PathBuf::from(env::var("OUT_DIR").unwrap());
    let (hdf5_src_path, cmake_file) = search_hdf5_source(out.clone());
    compile(hdf5_src_path, cmake_file);
}

fn compile(hdf5: PathBuf, mut cmake_file: File) {
    let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
    path.push("ext");
    path.push("bitshuffle");
    let src = {
        let src = [
            "lz4/lz4.c",
            "src/bitshuffle.c",
            "src/bitshuffle_core.c",
            "src/bshuf_h5filter.c",
            "src/bshuf_h5plugin.c",
            "src/iochain.c",
        ];
        let mut full = vec![];
        for s in &src {
            let path = path.clone().join(s);
            full.push(path);
        }
        full
    };
    let hdf5_include = hdf5.clone().join("include");
    let lz4_include = path.clone().join("lz4");
    cmake_file
        .write_all(lz4_include.to_str().unwrap().as_bytes())
        .unwrap();
    cmake_file.write_all(CMAKE_SEPARATOR).unwrap();
    let src_include = path.clone().join("src");
    cmake_file
        .write_all(src_include.to_str().unwrap().as_bytes())
        .unwrap();
    cc::Build::new()
        .files(src.iter())
        .flag("-w")
        .include(hdf5_include)
        .include(lz4_include)
        .include(src_include)
        .compile("bitshuffle");
}

struct Data {
    path: PathBuf,
    md: fs::Metadata,
}

fn search_hdf5_source(path: PathBuf) -> (PathBuf, File) {
    let path = PathBuf::from(path.parent().unwrap().parent().unwrap());
    let paths = fs::read_dir(&path).unwrap();
    let mut data: Option<Data> = None;
    for dir in paths {
        let dir = dir.unwrap();
        let md = dir.metadata().unwrap();
        if !md.is_dir() {
            continue;
        }
        if !dir.path().to_str().unwrap().contains("hdf5-src") {
            continue;
        }
        let out = dir.path().join("out");
        if !out.exists() {
            continue;
        }
        let lib = out.clone().join("lib");
        if !lib.exists() {
            continue;
        }
        data = Some(match data {
            None => Data { path: out, md },
            Some(ref data) => {
                if data.md.modified().unwrap() < md.modified().unwrap() {
                    Data { path: out, md }
                } else {
                    continue;
                }
            }
        });
    }
    match data {
        None => panic!("Cannot find hdf5-src build dir"),
        Some(data) => {
            let mut file =
                File::create(path.clone().parent().unwrap().join("cmake_cryiorust_hdf5")).unwrap();
            file.write_all(
                data.path
                    .clone()
                    .join("include")
                    .to_str()
                    .unwrap()
                    .as_bytes(),
            )
            .unwrap();
            file.write_all(CMAKE_SEPARATOR).unwrap();
            (data.path, file)
        }
    }
}