1use std::io::{BufWriter, Write};
2
3use ciborium::Value;
4
5use crate::error::MoqTraceError;
6use crate::event::TraceEvent;
7use crate::header::TraceHeader;
8
9pub const MOQTRACE_MAGIC: &[u8; 8] = b"MOQTRACE";
11
12pub const MOQTRACE_VERSION: u32 = 1;
14
15#[derive(Debug)]
25pub struct MoqTraceWriter<W: Write> {
26 inner: BufWriter<W>,
27}
28
29impl<W: Write> MoqTraceWriter<W> {
30 pub fn new(writer: W, header: &TraceHeader) -> Result<Self, MoqTraceError> {
32 let mut writer = BufWriter::new(writer);
33
34 writer.write_all(MOQTRACE_MAGIC)?;
36
37 writer.write_all(&MOQTRACE_VERSION.to_le_bytes())?;
39
40 let header_value: Value = header.into();
42 let mut header_bytes = Vec::with_capacity(128);
43 ciborium::into_writer(&header_value, &mut header_bytes)?;
44
45 let header_len = header_bytes.len() as u32;
47 writer.write_all(&header_len.to_le_bytes())?;
48
49 writer.write_all(&header_bytes)?;
51
52 Ok(Self { inner: writer })
53 }
54
55 pub fn write_event(&mut self, event: &TraceEvent) -> Result<(), MoqTraceError> {
57 ciborium::into_writer(event, &mut self.inner)?;
58 Ok(())
59 }
60
61 pub fn flush(&mut self) -> Result<(), MoqTraceError> {
63 self.inner.flush()?;
64 Ok(())
65 }
66
67 pub fn into_inner(self) -> Result<W, MoqTraceError> {
71 self.inner.into_inner().map_err(|e| MoqTraceError::Io(e.into_error()))
72 }
73}