1use std::{
7 fmt,
8 io::{self, Cursor, Read, Write},
9 mem::size_of,
10};
11
12use koibumi_net::Port;
13
14pub use crate::error::TooLongError;
15
16pub trait WriteTo {
18 fn write_to(&self, w: &mut dyn Write) -> io::Result<()>;
20}
21
22pub trait ReadFrom {
24 fn read_from(r: &mut dyn Read) -> io::Result<Self>
26 where
27 Self: Sized;
28}
29
30impl WriteTo for u8 {
31 fn write_to(&self, w: &mut dyn Write) -> io::Result<()> {
32 let bytes = [*self];
33 w.write_all(&bytes)
34 }
35}
36
37impl ReadFrom for u8 {
38 fn read_from(r: &mut dyn Read) -> io::Result<Self>
39 where
40 Self: Sized,
41 {
42 let mut buf = [0; 1];
43 r.read_exact(&mut buf)?;
44 Ok(buf[0])
45 }
46}
47
48impl WriteTo for u16 {
49 fn write_to(&self, w: &mut dyn Write) -> io::Result<()> {
50 w.write_all(&self.to_be_bytes())
51 }
52}
53
54impl ReadFrom for u16 {
55 fn read_from(r: &mut dyn Read) -> io::Result<Self>
56 where
57 Self: Sized,
58 {
59 let mut buf = [0; 2];
60 r.read_exact(&mut buf)?;
61 Ok(Self::from_be_bytes(buf))
62 }
63}
64
65impl WriteTo for u32 {
66 fn write_to(&self, w: &mut dyn Write) -> io::Result<()> {
67 w.write_all(&self.to_be_bytes())
68 }
69}
70
71impl ReadFrom for u32 {
72 fn read_from(r: &mut dyn Read) -> io::Result<Self>
73 where
74 Self: Sized,
75 {
76 let mut buf = [0; 4];
77 r.read_exact(&mut buf)?;
78 Ok(Self::from_be_bytes(buf))
79 }
80}
81
82impl WriteTo for u64 {
83 fn write_to(&self, w: &mut dyn Write) -> io::Result<()> {
84 w.write_all(&self.to_be_bytes())
85 }
86}
87
88impl ReadFrom for u64 {
89 fn read_from(r: &mut dyn Read) -> io::Result<Self>
90 where
91 Self: Sized,
92 {
93 let mut buf = [0; 8];
94 r.read_exact(&mut buf)?;
95 Ok(Self::from_be_bytes(buf))
96 }
97}
98
99impl WriteTo for [u8] {
100 fn write_to(&self, w: &mut dyn Write) -> io::Result<()> {
101 w.write_all(self)
102 }
103}
104
105macro_rules! io_array {
106 ($len:expr) => {
107 impl ReadFrom for [u8; $len] {
108 fn read_from(r: &mut dyn Read) -> io::Result<Self>
109 where
110 Self: Sized,
111 {
112 let mut buf = [0; $len];
113 r.read_exact(&mut buf)?;
114 Ok(buf)
115 }
116 }
117 };
118}
119
120io_array!(4);
121io_array!(6);
122io_array!(10);
123io_array!(12);
124io_array!(16);
125io_array!(18);
126io_array!(20);
127io_array!(32);
128
129impl WriteTo for Vec<u8> {
130 fn write_to(&self, w: &mut dyn Write) -> io::Result<()> {
131 w.write_all(self)
132 }
133}
134
135impl WriteTo for Port {
136 fn write_to(&self, w: &mut dyn Write) -> io::Result<()> {
137 self.as_u16().write_to(w)
138 }
139}
140
141impl ReadFrom for Port {
142 fn read_from(r: &mut dyn Read) -> io::Result<Self>
143 where
144 Self: Sized,
145 {
146 Ok(Self::new(u16::read_from(r)?))
147 }
148}
149
150#[derive(Clone, PartialEq, Eq, Debug)]
156pub struct TrailingBytesError(usize);
157
158impl fmt::Display for TrailingBytesError {
159 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
160 write!(f, "found trailing {} bytes", self.0)
161 }
162}
163
164impl std::error::Error for TrailingBytesError {}
165
166impl TrailingBytesError {
167 pub fn new(trailing_len: usize) -> Self {
169 Self(trailing_len)
170 }
171
172 pub fn trailing_len(&self) -> usize {
174 self.0
175 }
176}
177
178pub trait SizedReadFrom {
181 fn sized_read_from(r: &mut dyn Read, len: usize) -> io::Result<Self>
184 where
185 Self: Sized;
186}
187
188impl SizedReadFrom for Vec<u8> {
189 fn sized_read_from(r: &mut dyn Read, len: usize) -> io::Result<Self>
190 where
191 Self: Sized,
192 {
193 let mut r = r.take(len as u64);
194 let mut bytes = Vec::with_capacity(len);
195 r.read_to_end(&mut bytes)?;
196 Ok(bytes)
197 }
198}
199
200pub trait LimitedReadFrom {
203 fn limited_read_from(r: &mut dyn Read, max_len: usize) -> io::Result<Self>
206 where
207 Self: Sized;
208}
209
210pub trait ReadFromExact {
213 fn read_from_exact(bytes: impl AsRef<[u8]>) -> io::Result<Self>
216 where
217 Self: Sized;
218}
219
220impl<T> ReadFromExact for T
221where
222 T: ReadFrom,
223{
224 fn read_from_exact(bytes: impl AsRef<[u8]>) -> io::Result<Self>
225 where
226 Self: Sized,
227 {
228 let bytes = bytes.as_ref();
229 let mut cur = Cursor::new(bytes);
230 let v = Self::read_from(&mut cur)?;
231 if cur.position() != bytes.len() as u64 {
232 return Err(io::Error::new(
233 io::ErrorKind::Other,
234 TrailingBytesError(bytes.len() - cur.position() as usize),
235 ));
236 }
237 Ok(v)
238 }
239}
240
241pub trait SizedReadFromExact {
244 fn sized_read_from_exact(bytes: impl AsRef<[u8]>) -> io::Result<Self>
247 where
248 Self: Sized;
249}
250
251impl<T> SizedReadFromExact for T
252where
253 T: SizedReadFrom,
254{
255 fn sized_read_from_exact(bytes: impl AsRef<[u8]>) -> io::Result<Self>
256 where
257 Self: Sized,
258 {
259 let bytes = bytes.as_ref();
260 let mut cur = Cursor::new(bytes);
261 Self::sized_read_from(&mut cur, bytes.len())
262 }
263}
264
265pub trait LenBm {
268 fn len_bm(&self) -> usize;
271}
272
273impl LenBm for u32 {
274 fn len_bm(&self) -> usize {
275 size_of::<u32>()
276 }
277}
278
279impl LenBm for u64 {
280 fn len_bm(&self) -> usize {
281 size_of::<u64>()
282 }
283}