1#![feature(array_try_from_fn)]
2#![feature(split_array)]
3#![feature(trait_alias)]
4
5use thiserror::Error;
6
7#[derive(Debug, Error)]
8pub enum Error {
9 #[error("Expected {0} bytes")]
12 ExpectedBytes(u32),
13 #[error("Expected a value in the range {0:?}")]
15 ExpectedRange(std::ops::RangeInclusive<u32>),
16 #[error("Attempted to parse string with invalid utf8: {0:?}")]
18 InvalidUtf8(std::string::FromUtf8Error),
19 #[error("{needed_bytes} bytes are needed to store this item's length, but only {max_bytes} bytes are available. Try increasing `S`.")]
24 TooLarge {
25 needed_bytes: u32,
26 max_bytes: u32,
27 },
28 #[error("Encountered an invalid utf8 sequence")]
30 InvalidChar,
31}
32
33pub trait Size = Serialize + TryFrom<usize> + Into<usize>;
50
51pub trait Serialize: Sized {
65 fn from_bytes<S: Size>(b: &mut &[u8]) -> Result<Self, Error>;
66 fn into_bytes<S: Size>(&self, b: &mut Vec<u8>) -> Result<(), Error>;
67}
68
69macro_rules! impl_byte_serialize {
70 ($($t:ty),+) => {
71 $(
72 impl Serialize for $t {
73 fn from_bytes<S: Size>(b: &mut &[u8]) -> Result<Self, Error> { const SIZE: usize = std::mem::size_of::<$t>();
74
75 if SIZE > b.len() {return Err(Error::ExpectedBytes((SIZE - b.len()) as u32))};
76
77 let (bytes, rem) = b.split_array_ref::<SIZE>();
78 *b = rem;
79
80 Ok(<$t>::from_le_bytes(*bytes))
81 }
82
83 fn into_bytes<S: Size>(&self, b: &mut Vec<u8>) -> Result<(), Error> {
84 let bytes = self.to_le_bytes();
85
86 b.extend_from_slice(&bytes);
87
88 Ok(())
89 }
90 }
91 )+
92 }
93}
94
95impl_byte_serialize!(u8,u16,u32,u64,u128,usize,
96 i8,i16,i32,i64,i128,isize,
98 f32,f64);
99
100impl Serialize for char {
101 fn from_bytes<S: Size>(b: &mut &[u8]) -> Result<Self, Error> {
102 match char::from_u32(u32::from_bytes::<S>(b)?) {
103 Some(c) => Ok(c),
104 None => Err(Error::InvalidChar),
105 }
106 }
107
108 fn into_bytes<S: Size>(&self, b: &mut Vec<u8>) -> Result<(), Error> {
109 (*self as u32).into_bytes::<S>(b)
110 }
111}
112
113impl Serialize for bool {
114 fn from_bytes<S: Size>(b: &mut &[u8]) -> Result<Self, Error> {
115 let Some((byte, rem)) = b.split_first() else {return Err(Error::ExpectedBytes(1))};
116 *b = rem;
117
118 match byte {
119 0 => Ok(false),
120 1 => Ok(true),
121 _ => Err(Error::ExpectedRange(0..=1)),
122 }
123 }
124
125 fn into_bytes<S: Size>(&self, b: &mut Vec<u8>) -> Result<(), Error> {
126 (*self as u8).into_bytes::<S>(b)
127 }
128}
129
130macro_rules! impl_byte_serialize_tuple {
131 ( $($i:ident $n:tt),* ) => {
132 #[allow(unused_variables)]
133 impl<$($i : Serialize),*> Serialize for ( $($i,)* ) {
134 fn from_bytes<S: Size>(b: &mut &[u8]) -> Result<Self, Error> {
135 Ok((
136 $($i::from_bytes::<S>(b)?,)*
137 ))
138 }
139
140 fn into_bytes<S: Size>(&self, b: &mut Vec<u8>) -> Result<(), Error> {
141 $(self.$n.into_bytes::<S>(b)?;)*
142 Ok(())
143 }
144 }
145 }
146}
147
148impl_byte_serialize_tuple!();
149impl_byte_serialize_tuple!(A 0);
150impl_byte_serialize_tuple!(A 0, B 1);
151impl_byte_serialize_tuple!(A 0, B 1, C 2);
152impl_byte_serialize_tuple!(A 0, B 1, C 2, D 3);
153impl_byte_serialize_tuple!(A 0, B 1, C 2, D 3, E 4);
154impl_byte_serialize_tuple!(A 0, B 1, C 2, D 3, E 4, F 5);
155impl_byte_serialize_tuple!(A 0, B 1, C 2, D 3, E 4, F 5, G 6);
156impl_byte_serialize_tuple!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7);
157impl_byte_serialize_tuple!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, J 8);
158impl_byte_serialize_tuple!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, J 8, K 9);
159impl_byte_serialize_tuple!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, J 8, K 9, L 10);
160
161
162impl<B: Serialize, const N: usize> Serialize for [B; N] {
163 fn from_bytes<S: Size>(b: &mut &[u8]) -> Result<Self, Error> {
164 std::array::try_from_fn(|_| {
165 <B>::from_bytes::<S>(b)
166 })
167 }
168
169 fn into_bytes<S: Size>(&self, b: &mut Vec<u8>) -> Result<(), Error> {
170 self.iter().try_for_each(|inner| {
171 inner.into_bytes::<S>(b)
172 })
173 }
174}
175
176fn push_len<S: Size>(len: usize, b: &mut Vec<u8>) -> Result<(), Error> {
177 let len = match len.try_into() {
182 Ok(len) => len,
183 Err(_) => return Err(Error::TooLarge {
184 needed_bytes: len.ilog2(),
185 max_bytes: std::mem::size_of::<S>() as u32,
186 }),
187 };
188
189 S::into_bytes::<S>(&len, b)
190}
191
192impl<B: Serialize> Serialize for Vec<B> {
193 fn from_bytes<S: Size>(b: &mut &[u8]) -> Result<Self, Error> {
194 let len = match S::from_bytes::<S>(b)?.try_into() {
199 Ok(len) => len,
200 Err(_) => return Err(Error::TooLarge {
201 needed_bytes: std::mem::size_of::<S>() as u32,
202 max_bytes: std::mem::size_of::<usize>() as u32,
203 })
204 };
205
206 let mut v = Vec::with_capacity(len);
207
208 for _ in 0..len {
209 let next = <B>::from_bytes::<S>(b)?;
210 v.push(next);
211 }
212
213 Ok(v)
214 }
215
216 fn into_bytes<S: Size>(&self, b: &mut Vec<u8>) -> Result<(), Error> {
217 push_len::<S>(self.len(), b)?;
218
219 self.iter()
220 .try_for_each(|inner| {
221 inner.into_bytes::<S>(b)
222 })
223 }
224}
225
226impl<B: Serialize> Serialize for Box<[B]> {
227 fn from_bytes<S: Size>(b: &mut &[u8]) -> Result<Self, Error> {
228 Ok(<Vec<B>>::from_bytes::<S>(b)?.into_boxed_slice())
229 }
230
231 fn into_bytes<S: Size>(&self, b: &mut Vec<u8>) -> Result<(), Error> {
232 self.iter()
233 .try_for_each(|inner| {
234 inner.into_bytes::<S>(b)
235 })
236 }
237}
238
239impl<B: Serialize> Serialize for Box<B> {
240 fn from_bytes<S: Size>(b: &mut &[u8]) -> Result<Self, Error> {
241 Ok(Box::new(B::from_bytes::<S>(b)?))
242 }
243
244 fn into_bytes<S: Size>(&self, b: &mut Vec<u8>) -> Result<(), Error> {
245 B::into_bytes::<S>(self, b)
246 }
247}
248
249impl<B: Serialize> Serialize for Option<B> {
250 fn from_bytes<S: Size>(b: &mut &[u8]) -> Result<Self, Error> {
251 let is_some = bool::from_bytes::<S>(b)?;
252
253 match is_some {
254 false => Ok(None),
255 true => Ok(Some(B::from_bytes::<S>(b)?)),
256 }
257 }
258
259 fn into_bytes<S: Size>(&self, b: &mut Vec<u8>) -> Result<(), Error> {
260 self.is_some().into_bytes::<S>(b)?;
261
262 if let Some(inner) = self {
263 inner.into_bytes::<S>(b)?;
264 }
265
266 Ok(())
267 }
268}
269
270impl Serialize for String {
271 fn from_bytes<S: Size>(b: &mut &[u8]) -> Result<Self, Error> {
272 match std::string::String::from_utf8(<Vec<u8>>::from_bytes::<S>(b)?) {
273 Ok(s) => Ok(s),
274 Err(e) => Err(Error::InvalidUtf8(e)),
275 }
276 }
277
278 fn into_bytes<S: Size>(&self, b: &mut Vec<u8>) -> Result<(), Error> {
279 self.as_str().into_bytes::<S>(b)
280 }
281}
282
283impl Serialize for &str {
284 fn from_bytes<S: Size>(_b: &mut &[u8]) -> Result<Self, Error> {
286 panic!("Can't convert bytes to &'str. Try converting to an owned `String` instead")
287 }
288
289 fn into_bytes<S: Size>(&self, b: &mut Vec<u8>) -> Result<(), Error> {
290 push_len::<S>(self.len(), b)?;
291 b.extend_from_slice(self.as_bytes());
292
293 Ok(())
294 }
295}