criterion-polyglot 0.1.0

An extension trait for criterion providing benchmark methods for various non-Rust programming languages
Documentation
use std::process::Command;

use tempfile::TempPath;

use crate::{helper::{make_tempfile, get_criterion_env_var, reindent, make_spec_tempfile}, runner::CommunicatingBenchmark, BenchSpec};

const HARNESS: &str = include_str!("harness.py.in");
const PY_FRAGMENT_EXT: &str = ".py.in";

pub fn spawn(spec: BenchSpec) -> CommunicatingBenchmark {
    let harness = make_spec_tempfile(".py", HARNESS, &spec);

    let timed_file = make_indent_normalized_tempfile(spec.timed);
    let setup_file = spec.sample.map(make_indent_normalized_tempfile);
    let init_file = spec.global.map(make_indent_normalized_tempfile);

    let python_path = get_criterion_env_var("PYTHON", "python3");
    let mut command = Command::new(python_path);
    command.arg(&harness);
    if let Some(setup_path) = &setup_file {
        command.arg("--setup").arg(setup_path);
    }
    if let Some(init_path) = &init_file {
        command.arg("--init").arg(init_path);
    }
    command.arg(&timed_file);

    let temp_files = [Some(harness), Some(timed_file), setup_file, init_file]
        .into_iter()
        .flatten();
    CommunicatingBenchmark::start("Python 3", command, temp_files)
}

fn make_indent_normalized_tempfile(py_code: &str) -> TempPath {
    let py_code = reindent(py_code, 0);
    make_tempfile(PY_FRAGMENT_EXT, [&*py_code])
}