| 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)); |
| } |
| } |