1use std::io::Read;
2
3pub fn write_frame<W: std::io::Write>(writer: &mut W, message: &str) -> std::io::Result<usize> {
4 let size = u16::try_from(message.len());
5 if let Ok(size) = size {
6 let _ = writer.write(&size.to_le_bytes())?;
7 writer.write(message.as_bytes())
8 } else {
9 Err(std::io::Error::new(
10 std::io::ErrorKind::FileTooLarge,
11 "frame-protocol supports a maximum frame size of 65536",
12 ))
13 }
14}
15
16pub struct FrameReader<R> {
17 reader: R,
18}
19
20impl<R> FrameReader<R> {
21 pub fn new(reader: R) -> Self {
22 Self { reader }
23 }
24}
25
26impl<R: Read> Iterator for FrameReader<R> {
27 type Item = std::io::Result<String>;
28
29 fn next(&mut self) -> Option<Self::Item> {
30 let mut marker_buf = [0u8; 2];
31 let result = self.reader.read_exact(&mut marker_buf);
32 if let Err(err) = result {
33 return if let std::io::ErrorKind::UnexpectedEof = err.kind() {
34 None
35 } else {
36 Some(Err(err))
37 };
38 };
39
40 let size = u16::from_le_bytes(marker_buf);
41 let mut buf = String::with_capacity(size.into());
42 let result = self
43 .reader
44 .by_ref()
45 .take(size.into())
46 .read_to_string(&mut buf);
47
48 match result {
49 Ok(_) => Some(Ok(buf)),
50 Err(err) => Some(Err(err)),
51 }
52 }
53}
54
55#[cfg(test)]
56mod tests {
57 use super::*;
58
59 #[test]
60 fn read_write() {
61 let mut buffer: Vec<u8> = Vec::new();
62
63 write_frame(&mut buffer, "Hello World").unwrap();
64 write_frame(&mut buffer, "Test").unwrap();
65
66 let out: Result<Vec<String>, _> = FrameReader::new(buffer.as_slice()).collect();
67 let out: Vec<String> = out.unwrap();
68
69 assert_eq!(out, &["Hello World".to_string(), "Test".to_string()]);
70 }
71}