1#![deny(missing_docs)]
11
12pub mod quic;
14
15use gbp::{CodecError, GbpFrame};
16use tokio::io::{AsyncReadExt, AsyncWriteExt};
17use tokio::net::TcpStream;
18
19pub const MAX_FRAME: usize = 1 << 20;
21
22#[derive(Debug, thiserror::Error)]
24pub enum WireError {
25 #[error("io: {0}")]
27 Io(#[from] std::io::Error),
28 #[error("codec: {0}")]
30 Codec(#[from] CodecError),
31 #[error("frame too large: {size} bytes (max {max})")]
33 TooLarge {
34 size: usize,
36 max: usize,
38 },
39 #[error("quic: {0}")]
41 Quic(String),
42}
43
44impl WireError {
45 fn too_large(n: usize) -> Self {
46 Self::TooLarge {
47 size: n,
48 max: MAX_FRAME,
49 }
50 }
51}
52
53pub async fn write_frame(stream: &mut TcpStream, frame: &GbpFrame) -> Result<(), WireError> {
55 let bytes = frame.to_cbor();
56 write_blob(stream, &bytes).await
57}
58
59pub async fn read_frame(stream: &mut TcpStream) -> Result<GbpFrame, WireError> {
61 let buf = read_blob(stream).await?;
62 Ok(GbpFrame::from_cbor(&buf)?)
63}
64
65pub async fn write_blob(stream: &mut TcpStream, data: &[u8]) -> Result<(), WireError> {
68 if data.len() > MAX_FRAME {
69 return Err(WireError::too_large(data.len()));
70 }
71 let len = (data.len() as u32).to_le_bytes();
72 stream.write_all(&len).await?;
73 stream.write_all(data).await?;
74 stream.flush().await?;
75 Ok(())
76}
77
78pub async fn read_blob(stream: &mut TcpStream) -> Result<Vec<u8>, WireError> {
80 let mut len_buf = [0u8; 4];
81 stream.read_exact(&mut len_buf).await?;
82 let len = u32::from_le_bytes(len_buf) as usize;
83 if len > MAX_FRAME {
84 return Err(WireError::too_large(len));
85 }
86 let mut buf = vec![0u8; len];
87 stream.read_exact(&mut buf).await?;
88 Ok(buf)
89}