energy-bench 0.3.0

Methods for benchmarking the energy consumption of programs.
Documentation
use std::{fs::{self, File}, marker::PhantomData, path::Path};

use crate::{Metadata, RunResult};

pub struct OutputFiles<MD, const COLS: usize>
where
    MD: Metadata<COLS>,
{
    filename: String,
    wtr: Option<csv::Writer<File>>,
    _phantom: PhantomData<MD>,
}

impl<MD, const COLS: usize> OutputFiles<MD, COLS>
where
    MD: Metadata<COLS>,
{
    pub fn new(name: &str) -> Self {
        let name = sanitize_filename::sanitize(name);
        let date = chrono::offset::Local::now().format("%Y-%m-%d-%H-%M-%S").to_string();
        let filename = format!("{}-{}.csv", name, date);
        Self { filename, wtr: None, _phantom: PhantomData }
    }

    pub fn write_results(&mut self, metadata: &MD, run_results: &Vec<RunResult>) -> csv::Result<()> {
        let wtr = self.wtr.get_or_insert_with(|| {
            let mut wtr = create_file(&self.filename).unwrap();
            let keys = run_results[0].energy.keys().collect();
            Self::init_columns(&mut wtr, keys).unwrap();
            wtr
        });

        for run in run_results {
            for val in metadata.get_values() {
                wtr.write_field(val)?;
            }

            wtr.write_field(run.runtime.as_secs_f32().to_string())?;
            for val in run.energy.values() {
                wtr.write_field(val.to_string())?;
            }

            wtr.write_record(None::<&[u8]>)?;
        }

        Ok(())
    }

    fn init_columns(wtr: &mut csv::Writer<File>, keys: Vec<&String>) -> csv::Result<()> {
        for key in MD::get_header() {
            wtr.write_field(key)?;
        }

        wtr.write_field("Runtime (s)")?;
        for key in keys {
            wtr.write_field(key)?;
        }

        wtr.write_record(None::<&[u8]>)
    }
}

fn create_file(filename: &str) -> csv::Result<csv::Writer<File>> {
    const ROOT_DIR: &str = "energy-bench";
    let path = Path::new(ROOT_DIR).join(filename);
    fs::create_dir_all(ROOT_DIR)?;
    csv::Writer::from_path(path)
}