Skip to main content

thin_fetch/parcel/
encoder.rs

1use std::io::Write;
2
3use crate::{Error, WithError as _, bail};
4
5use super::{MARKER_END, MARKER_SEP};
6
7pub struct ParcelEncoder<W: Write> {
8    writer: W,
9}
10
11impl<W: Write> ParcelEncoder<W> {
12    pub fn new(writer: W) -> Self {
13        Self { writer }
14    }
15
16    /// Write a data packet to the output stream.
17    ///
18    /// # Errors
19    ///
20    /// Returns an error when data packet size exceeds 65531,
21    /// or when cannot write the data to the writer.
22    pub fn write_data(&mut self, data: &[u8]) -> Result<(), Error> {
23        let len = data.len() + 4;
24
25        let mut len_bytes = vec![];
26        write!(len_bytes, "{len:04x}").with_err_msg("could not format length")?;
27        if len_bytes.len() > 4 {
28            bail!("payload too long");
29        }
30
31        self.writer
32            .write_all(&len_bytes)
33            .with_err_msg("could not write length")?;
34
35        self.writer
36            .write_all(data)
37            .with_err_msg("could not write data")?;
38
39        Ok(())
40    }
41
42    /// Writes a section separator marker to the output stream.
43    ///
44    /// # Errors
45    ///
46    /// Returns an error when cannot write data to the writer.
47    pub fn new_section(&mut self) -> Result<(), Error> {
48        self.writer
49            .write_all(&MARKER_SEP)
50            .with_err_msg("could not write separator marker")
51    }
52
53    /// Writes a stream end marker to the output stream.
54    ///
55    /// # Errors
56    ///
57    /// Returns an error when cannot write data to the writer.
58    pub fn finish(mut self) -> Result<(), Error> {
59        self.writer
60            .write_all(&MARKER_END)
61            .with_err_msg("could not write end marker")
62    }
63}