use std::{
error::Error,
fs,
path::{Path, PathBuf},
};
use crate::{
TraceEventsFileFormat, TraceLowLevelEvent, TraceWriter,
abstract_trace_writer::{AbstractTraceWriter, AbstractTraceWriterData},
};
pub struct NonStreamingTraceWriter {
base: AbstractTraceWriterData,
pub events: Vec<TraceLowLevelEvent>,
format: TraceEventsFileFormat,
trace_events_path: Option<PathBuf>,
}
impl NonStreamingTraceWriter {
pub fn new(program: &str, args: &[String]) -> Self {
NonStreamingTraceWriter {
base: AbstractTraceWriterData::new(program, args),
events: vec![],
format: TraceEventsFileFormat::Binary,
trace_events_path: None,
}
}
pub fn set_format(&mut self, format: TraceEventsFileFormat) {
self.format = format;
}
}
impl AbstractTraceWriter for NonStreamingTraceWriter {
fn get_data(&self) -> &AbstractTraceWriterData {
&self.base
}
fn get_mut_data(&mut self) -> &mut AbstractTraceWriterData {
&mut self.base
}
fn add_event(&mut self, event: TraceLowLevelEvent) {
self.events.push(event)
}
fn append_events(&mut self, events: &mut Vec<TraceLowLevelEvent>) {
self.events.append(events)
}
}
impl TraceWriter for NonStreamingTraceWriter {
fn begin_writing_trace_events(&mut self, path: &Path) -> Result<(), Box<dyn Error>> {
self.trace_events_path = Some(path.to_path_buf());
Ok(())
}
fn finish_writing_trace_events(&mut self) -> Result<(), Box<dyn Error>> {
if let Some(path) = &self.trace_events_path {
match self.format {
TraceEventsFileFormat::Json => {
let json = serde_json::to_string(&self.events)?;
fs::write(path, json)?;
}
TraceEventsFileFormat::BinaryV0 => {
let mut file = fs::File::create(path)?;
crate::capnptrace::write_trace(&self.events, &mut file)?;
}
TraceEventsFileFormat::Binary => {
unreachable!()
}
}
Ok(())
} else {
panic!("finish_writing_trace_events() called without previous call to begin_writing_trace_events()");
}
}
}