use csv::Writer;
use error::Result;
use report::{BenchmarkId, MeasurementData, Report, ReportContext};
use std::io::Write;
#[derive(Serialize)]
struct CsvRow<'a> {
group: &'a str,
function: Option<&'a str>,
value: Option<&'a str>,
sample_time_nanos: f64,
iteration_count: u64,
}
struct CsvReportWriter<W: Write> {
writer: Writer<W>,
}
impl<W: Write> CsvReportWriter<W> {
fn write_data(&mut self, id: &BenchmarkId, data: &MeasurementData) -> Result<()> {
for (count, time) in data.iter_counts().iter().zip(data.sample_times().as_ref()) {
let row = CsvRow {
group: id.group_id.as_str(),
function: id.function_id.as_ref().map(String::as_str),
value: id.value_str.as_ref().map(String::as_str),
sample_time_nanos: *time,
iteration_count: (*count) as u64,
};
self.writer.serialize(row)?;
}
Ok(())
}
}
pub struct FileCsvReport;
impl FileCsvReport {
fn write_file(
&self,
path: String,
id: &BenchmarkId,
measurements: &MeasurementData,
) -> Result<()> {
let writer = Writer::from_path(path)?;
let mut writer = CsvReportWriter { writer };
writer.write_data(id, measurements)?;
Ok(())
}
}
impl Report for FileCsvReport {
fn measurement_complete(
&self,
id: &BenchmarkId,
context: &ReportContext,
measurements: &MeasurementData,
) {
let path = format!(
"{}/{}/new/raw.csv",
context.output_directory,
id.as_directory_name()
);
log_if_err!(self.write_file(path, id, measurements));
}
}