use serde::Serialize; #[derive(Clone, Serialize, Debug)] pub struct FrameTiming { pub pts_ms: Option, pub dts_ms: u64, } #[derive(Clone, Serialize, Debug)] pub struct RecordedFrame { pub timing: FrameTiming, pub frame: F, } #[derive(Clone, Default)] pub struct Recording { pub frames: Vec>, pub count: usize, pub except_count: Option, } impl Recording { pub fn new() -> Recording { Self { frames: Vec::new(), count: 0, except_count: None, } } pub fn with_except_count(except_count: usize) -> Recording { Self { frames: Vec::new(), count: 0, except_count: Some(except_count), } } pub fn push(&mut self, ite: RecordedFrame) { self.frames.push(ite); } pub fn check_frame_need_record(_ite: RecordedFrame) {} } pub trait CsvExporter { type Error: std::error::Error + Send + Sync + 'static; fn csv_header(&self, recording: &Recording) -> Vec; fn csv_row(&self, item: &RecordedFrame) -> anyhow::Result>>; } // TODO: CsvImporter pub trait CsvImporter

{ fn load(&mut self, reader: R) -> anyhow::Result>; } pub fn write_csv(recording: &Recording, exporter: &E, writer: W) -> anyhow::Result<()> where E: CsvExporter, W: std::io::Write, { let header = exporter.csv_header(&recording); let mut wrt = csv::Writer::from_writer(writer); wrt.write_record(header)?; for f in &recording.frames { if let Some(row) = exporter.csv_row(f)? { wrt.write_record(&row)?; } } wrt.flush()?; Ok(()) }