nbindgen 0.0.1

A tool for generating Nim bindings to Rust code (based on cbindgen).
Documentation
extern crate nbindgen;

use std::path::Path;
use std::process::Command;
use std::{env, fs, str};

fn run_cbindgen(cbindgen_path: &'static str, path: &Path, output: &Path) {
    let program = Path::new(cbindgen_path);
    let mut command = Command::new(&program);

    command.arg("-o").arg(output);

    if env::var("NBINDGEN_TEST_VERIFY").is_ok() {
        command.arg("--verify");
    }

    let mut config = path.clone().to_path_buf();
    config.set_extension("toml");
    if config.exists() {
        command.arg("--config").arg(config);
    }

    command.arg(path);

    println!("Running: {:?}", command);
    let cbindgen_output = command.output().expect("failed to execute process");
    assert!(
        cbindgen_output.status.success(),
        "cbindgen failed: {:?} with error: {}",
        output,
        str::from_utf8(&cbindgen_output.stderr).unwrap_or_default()
    );
}

fn compile(cbindgen_output: &Path) {
    let cc = "nim";

    let mut object = cbindgen_output.to_path_buf();
    object.set_extension("o");

    let mut command = Command::new(cc);
    command.arg("check").arg(cbindgen_output);

    println!("Running: {:?}", command);
    let out = command.output().expect("failed to compile");
    assert!(out.status.success(), "Output failed to compile: {:?}", out);

    if object.exists() {
        fs::remove_file(object).unwrap();
    }
}

fn run_compile_test(cbindgen_path: &'static str, name: &'static str, path: &Path) {
    let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
    let mut output = Path::new(&crate_dir).join("tests").join("expectations");
    output.push(format!("{}.nim", name.replace("-", "_")));

    run_cbindgen(cbindgen_path, path, &output);
    compile(&output);
}

fn test_file(cbindgen_path: &'static str, name: &'static str, filename: &'static str) {
    let test = Path::new(filename);
    run_compile_test(cbindgen_path, name, &test);
}

macro_rules! test_file {
    ($cbindgen_path:expr, $test_function_name:ident, $name:expr, $file:tt) => {
        #[test]
        fn $test_function_name() {
            test_file($cbindgen_path, $name, $file);
        }
    };
}

// This file is generated by build.rs
include!(concat!(env!("OUT_DIR"), "/tests.rs"));