1use std::io::{self, Read, Write};
6
7use crate::Schema;
8
9pub type Len = u32;
11pub const MAX_FRAME: usize = 256 << 20;
13
14pub fn write_frame<T: Schema>(w: &mut impl Write, message: &T) -> io::Result<()> {
16 write_frame_bytes(w, &crate::to_bytes(message))
17}
18
19pub fn write_frame_bytes(w: &mut impl Write, bytes: &[u8]) -> io::Result<()> {
21 let len = Len::try_from(bytes.len())
22 .ok()
23 .filter(|_| bytes.len() <= MAX_FRAME)
24 .ok_or_else(|| io::Error::new(io::ErrorKind::InvalidInput, "frame too long"))?;
25 let mut frame = Vec::with_capacity(size_of::<Len>() + bytes.len());
27 frame.extend_from_slice(&len.to_le_bytes());
28 frame.extend_from_slice(bytes);
29 w.write_all(&frame)?;
30 w.flush()
31}
32
33pub fn read_frame_bytes(r: &mut impl Read) -> io::Result<Option<Vec<u8>>> {
35 let mut len = [0; size_of::<Len>()];
36 match r.read_exact(&mut len) {
37 Err(e) if e.kind() == io::ErrorKind::UnexpectedEof => return Ok(None),
38 other => other?,
39 }
40 let len = Len::from_le_bytes(len) as usize;
41 if len > MAX_FRAME {
42 return Err(io::Error::new(io::ErrorKind::InvalidData, "frame too long"));
43 }
44 let mut bytes = vec![0; len];
45 r.read_exact(&mut bytes)?;
46 Ok(Some(bytes))
47}
48
49pub fn read_frame<T: Schema>(r: &mut impl Read) -> io::Result<Option<T>> {
51 let Some(bytes) = read_frame_bytes(r)? else {
52 return Ok(None);
53 };
54 crate::read_bytes(&bytes)
55 .map(Some)
56 .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, format!("{e:?}")))
57}
58
59#[cfg(test)]
60mod tests;