65 lines
1.4 KiB
Rust
65 lines
1.4 KiB
Rust
use std::fs::{write, File};
|
|
use std::io;
|
|
use anyhow::{Result, anyhow};
|
|
use csv::Reader;
|
|
|
|
#[derive(Clone)]
|
|
pub struct FrameTiming {
|
|
pub pts_ms: Option<u64>,
|
|
pub dts_ms: u64,
|
|
}
|
|
|
|
#[derive(Clone)]
|
|
pub struct RecordedFrame<F> {
|
|
pub timing: FrameTiming,
|
|
pub frame: F
|
|
}
|
|
|
|
#[derive(Clone, Default)]
|
|
pub struct Recording<F> {
|
|
pub frames: Vec<RecordedFrame<F>>
|
|
}
|
|
|
|
impl<F> Recording<F> {
|
|
pub fn new() -> Recording<F> { Self { frames: Vec::new() } }
|
|
pub fn push(&mut self, ite: RecordedFrame<F>) {
|
|
self.frames.push(ite);
|
|
}
|
|
}
|
|
|
|
pub trait CsvExporter<F> {
|
|
type Error: std::error::Error + Send + Sync + 'static;
|
|
fn csv_header(&self, recording: &Recording<F>) -> Vec<String>;
|
|
fn csv_row(&self, item: &RecordedFrame<F>) -> anyhow::Result<Vec<String>>;
|
|
}
|
|
|
|
// TODO: CsvImporter
|
|
pub trait CsvImporter<P> {
|
|
fn load<R: std::io::Read>(&mut self, reader: R) -> anyhow::Result<Vec<P>>;
|
|
}
|
|
|
|
pub fn write_csv<F, E>(
|
|
recording: &Recording<F>,
|
|
exporter: &E,
|
|
path: &str
|
|
// mut writer: W,
|
|
) -> anyhow::Result<()>
|
|
where
|
|
E: CsvExporter<F>,
|
|
// W: std::io::Write
|
|
{
|
|
let header = exporter.csv_header(&recording);
|
|
// let mut wrt = csv::Writer::from_writer(io::stdout());
|
|
|
|
let mut wrt = csv::Writer::from_path(format!("{}.csv", path))?;
|
|
wrt.write_record(header)?;
|
|
for f in &recording.frames {
|
|
let row = exporter.csv_row(f)?;
|
|
wrt.write_record(&row)?;
|
|
}
|
|
|
|
wrt.flush()?;
|
|
|
|
Ok(())
|
|
}
|