mastrust-ls-lib 0.1.0

mastrust language server library for rust
Documentation
use std::env;
use std::path::PathBuf;

#[allow(unused)]
fn get_out_dir() -> PathBuf {
    let _raw = env::var("OUT_DIR");
    let _out = if _raw.is_ok() {
        PathBuf::from(_raw.unwrap())
    } else {
        let _tmp = env::temp_dir();
        let out = _tmp.join("out");
        env::set_var("OUT_DIR", out.to_str().unwrap());
        std::fs::create_dir_all(&out).expect("could not create temp dir");
        out
    };
    _out
}

#[allow(unused)]
fn build_bootstrap(name: &str, out_dir: &PathBuf) {
    // Here define wir now our flex version.
    let libdir_path = PathBuf::from("include")
        .canonicalize()
        .expect("cannot canonicalize path");

    let headers_path = libdir_path.join(format!("{}.h", name));
    let obj_path = libdir_path.join(format!("{}.o", name));
    let lib_path = libdir_path.join(format!("lib{}.a", name));

    let headers_path_str = headers_path.to_str().expect("Path is not a valid string");
    let lib_path_str = lib_path.to_str().expect("Path is not a valid string");

    println!("cargo:rustc-link-search={}", libdir_path.to_str().unwrap());
    println!("cargo:rustc-link-lib={}", name);

    if !std::process::Command::new("clang")
        .arg("-c")
        .arg("-o")
        .arg(&obj_path)
        .arg("-I")
        .arg(&libdir_path)
        .arg(&libdir_path.join(format!("{}.c", name)))
        .output()
        .expect("could not spawn `clang`")
        .status
        .success()
    {
        panic!("could not compile object file");
    }

    if !std::process::Command::new("ar")
        .arg("rcs")
        .arg(&lib_path_str)
        .arg(obj_path)
        .output()
        .expect("could not spawn `ar`")
        .status
        .success()
    {
        panic!("could not emit library file");
    }

    let tmp = lib_path_str;
    // The bindgen::Builder is the main entry point
    // to bindgen, and lets you build up options for
    // the resulting bindings.
    let bind = bindgen::CargoCallbacks::new();
    let bindings = bindgen::Builder::default()
        // The input header we would like to generate
        // bindings for.
        .header(headers_path_str)
        .clang_arg(format!("-l{}", name))
        // Tell cargo to invalidate the built crate whenever any of the
        // included header files changed.
        .parse_callbacks(Box::new(bind))
        // Finish the builder and generate the bindings.
        .generate()
        // Unwrap the Result and panic on failure.
        .expect("Unable to generate bindings");

    let out_path = PathBuf::from(out_dir).join(format!("{}_bindings.rs", name));
    bindings
        .write_to_file(out_path)
        .expect("Couldn't write bindings!");
}

#[allow(unused)]
fn build_mastrust_header(out_dir: &PathBuf) {
    // Here define wir now our flex version.
    let name: &str = "mastrust";
    let libdir_path = PathBuf::from("include")
        .canonicalize()
        .expect("cannot canonicalize path");

    let headers_path = libdir_path.join(format!("{}.h", name));
    let obj_path = out_dir.join(format!("{}.o", name));
    let lib_path = out_dir.join(format!("lib{}.a", name));

    let headers_path_str = headers_path.to_str().expect("Path is not a valid string");
    let lib_path_str = lib_path.to_str().expect("Path is not a valid string");

    println!("cargo:rustc-link-search={}", libdir_path.to_str().unwrap());
    println!("cargo:rustc-link-lib={}", name);

    if !std::process::Command::new("clang")
        .arg("-c")
        .arg("-o")
        .arg(&obj_path)
        .arg("-I")
        .arg(&libdir_path)
        .arg(&libdir_path.join(format!("{}.c", name)))
        .output()
        .expect("could not spawn `clang`")
        .status
        .success()
    {
        panic!("could not compile object file");
    }

    if !std::process::Command::new("ar")
        .arg("rcs")
        .arg(lib_path_str)
        .arg(obj_path)
        .output()
        .expect("could not spawn `ar`")
        .status
        .success()
    {
        panic!("could not emit library file");
    }

    let tmp = lib_path_str;
    // The bindgen::Builder is the main entry point
    // to bindgen, and lets you build up options for
    // the resulting bindings.
    let bind = bindgen::CargoCallbacks::new();
    let bindings = bindgen::Builder::default()
        // The input header we would like to generate
        // bindings for.
        .header(headers_path_str)
        .clang_arg(format!("-l{}", name))
        .allowlist_type("CToken")
        .allowlist_type("CBufferFile")
        .allowlist_function("ctoken_init")
        .allowlist_function("ctoken_tokenize")
        .allowlist_function("ctoken_get_token")
        .allowlist_function("ctoken_get_string")
        .allowlist_function("ctoken_get_type")
        .allowlist_function("ctoken_get_size")
        // Tell cargo to invalidate the built crate whenever any of the
        // included header files changed.
        .parse_callbacks(Box::new(bind))
        // Finish the builder and generate the bindings.
        .generate()
        // Unwrap the Result and panic on failure.
        .expect("Unable to generate bindings");

    // Write the bindings to the $OUT_DIR/bindings.rs file.
    let out_path = PathBuf::from(out_dir).join(format!("{}_bindings.rs", name));
    bindings
        .write_to_file(out_path)
        .expect("Couldn't write bindings!");
}


fn main() {
    let out_dir = get_out_dir();
    build_mastrust_header(&out_dir);
}