rustbac_core/encoding/
writer.rs1use crate::EncodeError;
2
3#[derive(Debug)]
8pub struct Writer<'a> {
9 buf: &'a mut [u8],
10 pos: usize,
11}
12
13impl<'a> Writer<'a> {
14 pub fn new(buf: &'a mut [u8]) -> Self {
15 Self { buf, pos: 0 }
16 }
17
18 pub const fn position(&self) -> usize {
19 self.pos
20 }
21
22 pub fn remaining(&self) -> usize {
23 self.buf.len().saturating_sub(self.pos)
24 }
25
26 pub fn as_written(&self) -> &[u8] {
27 &self.buf[..self.pos]
28 }
29
30 pub fn write_u8(&mut self, value: u8) -> Result<(), EncodeError> {
31 if self.remaining() < 1 {
32 return Err(EncodeError::BufferTooSmall);
33 }
34 self.buf[self.pos] = value;
35 self.pos += 1;
36 Ok(())
37 }
38
39 pub fn write_all(&mut self, data: &[u8]) -> Result<(), EncodeError> {
40 if self.remaining() < data.len() {
41 return Err(EncodeError::BufferTooSmall);
42 }
43 let end = self.pos + data.len();
44 self.buf[self.pos..end].copy_from_slice(data);
45 self.pos = end;
46 Ok(())
47 }
48
49 pub fn write_be_u16(&mut self, value: u16) -> Result<(), EncodeError> {
50 self.write_all(&value.to_be_bytes())
51 }
52
53 pub fn write_be_u32(&mut self, value: u32) -> Result<(), EncodeError> {
54 self.write_all(&value.to_be_bytes())
55 }
56}
57
58#[cfg(test)]
59mod tests {
60 use super::Writer;
61 use crate::EncodeError;
62
63 #[test]
64 fn writer_writes_values() {
65 let mut buf = [0u8; 4];
66 let mut w = Writer::new(&mut buf);
67 w.write_u8(1).unwrap();
68 w.write_all(&[2, 3]).unwrap();
69 assert_eq!(w.as_written(), &[1, 2, 3]);
70 }
71
72 #[test]
73 fn writer_bounds() {
74 let mut buf = [0u8; 1];
75 let mut w = Writer::new(&mut buf);
76 w.write_u8(1).unwrap();
77 assert_eq!(w.write_u8(2).unwrap_err(), EncodeError::BufferTooSmall);
78 }
79}