1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
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)); } }