Skip to main content

ferroui_base/rendering/composition/drawing/
render_data_reader.rs

1use super::{IRenderDataPayload, RenderDataOpcode};
2use crate::rendering::composition::transport::{BatchValue, BatchValueReader};
3
4/// Reads back what a [`RenderDataWriter`](super::RenderDataWriter) wrote.
5/// Reading past the end panics, as the span slicing of upstream throws.
6#[derive(Clone, Copy, Debug)]
7pub struct RenderDataReader<'a> {
8    buffer: &'a [u8],
9    position: usize,
10}
11
12impl<'a> RenderDataReader<'a> {
13    pub fn new(buffer: &'a [u8]) -> Self {
14        Self { buffer, position: 0 }
15    }
16
17    /// The offset of the next byte to read.
18    pub fn position(&self) -> usize {
19        self.position
20    }
21
22    /// Whether every byte has been read.
23    pub fn is_at_end(&self) -> bool {
24        self.position >= self.buffer.len()
25    }
26
27    /// Takes the next `count` bytes.
28    pub fn take(&mut self, count: usize) -> &'a [u8] {
29        let span = &self.buffer[self.position..self.position + count];
30        self.position += count;
31        span
32    }
33
34    /// Reads the next value.
35    pub fn read<T: BatchValue>(&mut self) -> T {
36        T::read_from(&mut BatchValueReader::new(self.buffer, &mut self.position))
37    }
38
39    /// Reads the next value without advancing.
40    pub fn peek<T: BatchValue>(&self) -> T {
41        let mut position = self.position;
42        T::read_from(&mut BatchValueReader::new(self.buffer, &mut position))
43    }
44
45    /// Reads the opcode of a payload, then the payload.
46    pub fn read_payload<T: IRenderDataPayload>(&mut self) -> T {
47        let opcode = self.read::<RenderDataOpcode>();
48        debug_assert_eq!(opcode, T::OPCODE);
49        self.read::<T>()
50    }
51}