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