Skip to main content

gaia_binary/
writer.rs

1use crate::{traits::BinaryFormat, TrackingWriter};
2use gaia_types::GaiaError;
3use std::io::Write;
4
5/// Generic binary writer with position tracking.
6pub struct BinaryWriter<W: Write, F: BinaryFormat> {
7    inner: TrackingWriter<W>,
8    diagnostics: Vec<GaiaError>,
9    _marker: std::marker::PhantomData<F>,
10}
11
12impl<W: Write, F: BinaryFormat> BinaryWriter<W, F> {
13    /// Create a new binary writer.
14    pub fn new(inner: W) -> Self {
15        Self { inner: TrackingWriter { inner, position: 0 }, diagnostics: Vec::new(), _marker: std::marker::PhantomData }
16    }
17
18    /// Get current position.
19    pub fn position(&self) -> u64 {
20        self.inner.position
21    }
22
23    /// Add a diagnostic error.
24    pub fn add_error(&mut self, error: GaiaError) {
25        self.diagnostics.push(error);
26    }
27
28    /// Take all collected diagnostic errors.
29    pub fn take_errors(&mut self) -> Vec<GaiaError> {
30        std::mem::take(&mut self.diagnostics)
31    }
32
33    /// Write a u8 value.
34    pub fn write_u8(&mut self, value: u8) -> std::io::Result<()> {
35        self.inner.write_all(&[value])
36    }
37
38    /// Write a u16 value.
39    pub fn write_u16(&mut self, value: u16) -> std::io::Result<()> {
40        F::write_u16(&mut self.inner, value)
41    }
42
43    /// Write a u32 value.
44    pub fn write_u32(&mut self, value: u32) -> std::io::Result<()> {
45        F::write_u32(&mut self.inner, value)
46    }
47
48    /// Write a u64 value.
49    pub fn write_u64(&mut self, value: u64) -> std::io::Result<()> {
50        F::write_u64(&mut self.inner, value)
51    }
52
53    /// Write an i16 value.
54    pub fn write_i16(&mut self, value: i16) -> std::io::Result<()> {
55        F::write_i16(&mut self.inner, value)
56    }
57
58    /// Write an i32 value.
59    pub fn write_i32(&mut self, value: i32) -> std::io::Result<()> {
60        F::write_i32(&mut self.inner, value)
61    }
62
63    /// Write an i64 value.
64    pub fn write_i64(&mut self, value: i64) -> std::io::Result<()> {
65        F::write_i64(&mut self.inner, value)
66    }
67
68    /// Write an f32 value.
69    pub fn write_f32(&mut self, value: f32) -> std::io::Result<()> {
70        F::write_f32(&mut self.inner, value)
71    }
72
73    /// Write an f64 value.
74    pub fn write_f64(&mut self, value: f64) -> std::io::Result<()> {
75        F::write_f64(&mut self.inner, value)
76    }
77
78    /// Write raw bytes.
79    pub fn write_bytes(&mut self, buf: &[u8]) -> std::io::Result<()> {
80        self.inner.write_all(buf)
81    }
82
83    /// Write all bytes from a slice.
84    pub fn write_all(&mut self, buf: &[u8]) -> std::io::Result<()> {
85        self.inner.write_all(buf)
86    }
87
88    /// Flush the writer.
89    pub fn flush(&mut self) -> std::io::Result<()> {
90        self.inner.flush()
91    }
92
93    /// Consume the writer and return the inner writer.
94    pub fn into_inner(self) -> W {
95        self.inner.inner
96    }
97}
98
99impl<W: Write + std::io::Seek, F: BinaryFormat> std::io::Seek for BinaryWriter<W, F> {
100    fn seek(&mut self, pos: std::io::SeekFrom) -> std::io::Result<u64> {
101        self.inner.seek(pos)
102    }
103}
104
105impl<W: Write + std::fmt::Debug, F: BinaryFormat> std::fmt::Debug for BinaryWriter<W, F> {
106    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
107        f.debug_struct("BinaryWriter").field("inner", &self.inner).field("position", &self.position()).finish()
108    }
109}