Skip to main content

binius_utils/
serialization.rs

1// Copyright 2024-2025 Irreducible Inc.
2
3use bytes::{Buf, BufMut};
4use hybrid_array::{Array, ArraySize};
5use thiserror::Error;
6
7/// Serialize data to a byte buffer.
8pub trait SerializeBytes {
9	fn serialize(&self, write_buf: impl BufMut) -> Result<(), SerializationError>;
10}
11
12/// Deserialize data from a byte buffer.
13pub trait DeserializeBytes: Sized {
14	fn deserialize(read_buf: impl Buf) -> Result<Self, SerializationError>;
15}
16
17/// A type whose byte-serialized form has a fixed, compile-time-known size.
18///
19/// Implementors must guarantee that [`SerializeBytes::serialize`] writes exactly
20/// [`BYTE_SIZE`](Self::BYTE_SIZE) bytes and that [`DeserializeBytes::deserialize`] reads exactly
21/// [`BYTE_SIZE`](Self::BYTE_SIZE) bytes.
22pub trait FixedSizeSerializeBytes: SerializeBytes + DeserializeBytes {
23	/// The exact number of bytes written by `serialize` and read by `deserialize`.
24	const BYTE_SIZE: usize;
25}
26
27macro_rules! impl_fixed_size_serialize_bytes {
28	($ty:ty, $size:expr) => {
29		impl FixedSizeSerializeBytes for $ty {
30			const BYTE_SIZE: usize = $size;
31		}
32	};
33}
34
35impl_fixed_size_serialize_bytes!(u8, 1);
36impl_fixed_size_serialize_bytes!(u16, 2);
37impl_fixed_size_serialize_bytes!(u32, 4);
38impl_fixed_size_serialize_bytes!(u64, 8);
39impl_fixed_size_serialize_bytes!(u128, 16);
40// `usize` is serialized as a `u32`.
41impl_fixed_size_serialize_bytes!(usize, 4);
42impl_fixed_size_serialize_bytes!(bool, 1);
43
44#[derive(Error, Debug, Clone)]
45pub enum SerializationError {
46	#[error("Write buffer is full")]
47	WriteBufferFull,
48	#[error("Not enough data in read buffer to deserialize")]
49	NotEnoughBytes,
50	#[error("Unknown enum variant index {name}::{index}")]
51	UnknownEnumVariant { name: &'static str, index: u8 },
52	#[error("Serialization has not been implemented")]
53	SerializationNotImplemented,
54	#[error("Deserializer has not been implemented")]
55	DeserializerNotImplemented,
56	#[error("Multiple deserializers with the same name {name} has been registered")]
57	DeserializerNameConflict { name: String },
58	#[error("FromUtf8Error: {0}")]
59	FromUtf8Error(#[from] std::string::FromUtf8Error),
60	#[error("Invalid construction of {name}")]
61	InvalidConstruction { name: &'static str },
62	#[error("usize {size} is too large to serialize (max is {max})", max = u32::MAX)]
63	UsizeTooLarge { size: usize },
64}
65
66impl<T: SerializeBytes + ?Sized> SerializeBytes for &T {
67	fn serialize(&self, write_buf: impl BufMut) -> Result<(), SerializationError> {
68		(**self).serialize(write_buf)
69	}
70}
71
72impl SerializeBytes for usize {
73	fn serialize(&self, mut write_buf: impl BufMut) -> Result<(), SerializationError> {
74		let value: u32 = (*self)
75			.try_into()
76			.map_err(|_| SerializationError::UsizeTooLarge { size: *self })?;
77		SerializeBytes::serialize(&value, &mut write_buf)
78	}
79}
80
81impl DeserializeBytes for usize {
82	fn deserialize(mut read_buf: impl Buf) -> Result<Self, SerializationError>
83	where
84		Self: Sized,
85	{
86		let value: u32 = DeserializeBytes::deserialize(&mut read_buf)?;
87		Ok(value as Self)
88	}
89}
90
91impl SerializeBytes for u128 {
92	fn serialize(&self, mut write_buf: impl BufMut) -> Result<(), SerializationError> {
93		assert_enough_space_for(&write_buf, std::mem::size_of::<Self>())?;
94		write_buf.put_u128_le(*self);
95		Ok(())
96	}
97}
98
99impl DeserializeBytes for u128 {
100	fn deserialize(mut read_buf: impl Buf) -> Result<Self, SerializationError>
101	where
102		Self: Sized,
103	{
104		assert_enough_data_for(&read_buf, std::mem::size_of::<Self>())?;
105		Ok(read_buf.get_u128_le())
106	}
107}
108
109impl SerializeBytes for u64 {
110	fn serialize(&self, mut write_buf: impl BufMut) -> Result<(), SerializationError> {
111		assert_enough_space_for(&write_buf, std::mem::size_of::<Self>())?;
112		write_buf.put_u64_le(*self);
113		Ok(())
114	}
115}
116
117impl DeserializeBytes for u64 {
118	fn deserialize(mut read_buf: impl Buf) -> Result<Self, SerializationError>
119	where
120		Self: Sized,
121	{
122		assert_enough_data_for(&read_buf, std::mem::size_of::<Self>())?;
123		Ok(read_buf.get_u64_le())
124	}
125}
126
127impl SerializeBytes for u32 {
128	fn serialize(&self, mut write_buf: impl BufMut) -> Result<(), SerializationError> {
129		assert_enough_space_for(&write_buf, std::mem::size_of::<Self>())?;
130		write_buf.put_u32_le(*self);
131		Ok(())
132	}
133}
134
135impl DeserializeBytes for u32 {
136	fn deserialize(mut read_buf: impl Buf) -> Result<Self, SerializationError>
137	where
138		Self: Sized,
139	{
140		assert_enough_data_for(&read_buf, std::mem::size_of::<Self>())?;
141		Ok(read_buf.get_u32_le())
142	}
143}
144
145impl SerializeBytes for u16 {
146	fn serialize(&self, mut write_buf: impl BufMut) -> Result<(), SerializationError> {
147		assert_enough_space_for(&write_buf, std::mem::size_of::<Self>())?;
148		write_buf.put_u16_le(*self);
149		Ok(())
150	}
151}
152
153impl DeserializeBytes for u16 {
154	fn deserialize(mut read_buf: impl Buf) -> Result<Self, SerializationError>
155	where
156		Self: Sized,
157	{
158		assert_enough_data_for(&read_buf, std::mem::size_of::<Self>())?;
159		Ok(read_buf.get_u16_le())
160	}
161}
162
163impl SerializeBytes for u8 {
164	fn serialize(&self, mut write_buf: impl BufMut) -> Result<(), SerializationError> {
165		assert_enough_space_for(&write_buf, std::mem::size_of::<Self>())?;
166		write_buf.put_u8(*self);
167		Ok(())
168	}
169}
170
171impl DeserializeBytes for u8 {
172	fn deserialize(mut read_buf: impl Buf) -> Result<Self, SerializationError>
173	where
174		Self: Sized,
175	{
176		assert_enough_data_for(&read_buf, std::mem::size_of::<Self>())?;
177		Ok(read_buf.get_u8())
178	}
179}
180
181impl SerializeBytes for bool {
182	fn serialize(&self, write_buf: impl BufMut) -> Result<(), SerializationError> {
183		u8::serialize(&(*self as u8), write_buf)
184	}
185}
186
187impl DeserializeBytes for bool {
188	fn deserialize(read_buf: impl Buf) -> Result<Self, SerializationError>
189	where
190		Self: Sized,
191	{
192		Ok(u8::deserialize(read_buf)? != 0)
193	}
194}
195
196impl<T> SerializeBytes for std::marker::PhantomData<T> {
197	fn serialize(&self, _write_buf: impl BufMut) -> Result<(), SerializationError> {
198		Ok(())
199	}
200}
201
202impl<T> DeserializeBytes for std::marker::PhantomData<T> {
203	fn deserialize(_read_buf: impl Buf) -> Result<Self, SerializationError>
204	where
205		Self: Sized,
206	{
207		Ok(Self)
208	}
209}
210
211impl SerializeBytes for &str {
212	fn serialize(&self, mut write_buf: impl BufMut) -> Result<(), SerializationError> {
213		let bytes = self.as_bytes();
214		SerializeBytes::serialize(&bytes.len(), &mut write_buf)?;
215		assert_enough_space_for(&write_buf, bytes.len())?;
216		write_buf.put_slice(bytes);
217		Ok(())
218	}
219}
220
221impl SerializeBytes for String {
222	fn serialize(&self, mut write_buf: impl BufMut) -> Result<(), SerializationError> {
223		SerializeBytes::serialize(&self.as_str(), &mut write_buf)
224	}
225}
226
227impl DeserializeBytes for String {
228	fn deserialize(mut read_buf: impl Buf) -> Result<Self, SerializationError>
229	where
230		Self: Sized,
231	{
232		let len = DeserializeBytes::deserialize(&mut read_buf)?;
233		assert_enough_data_for(&read_buf, len)?;
234		Ok(Self::from_utf8(read_buf.copy_to_bytes(len).to_vec())?)
235	}
236}
237
238impl<T: SerializeBytes> SerializeBytes for [T] {
239	fn serialize(&self, mut write_buf: impl BufMut) -> Result<(), SerializationError> {
240		SerializeBytes::serialize(&self.len(), &mut write_buf)?;
241		self.iter()
242			.try_for_each(|item| SerializeBytes::serialize(item, &mut write_buf))
243	}
244}
245
246impl<T: SerializeBytes> SerializeBytes for Vec<T> {
247	fn serialize(&self, mut write_buf: impl BufMut) -> Result<(), SerializationError> {
248		SerializeBytes::serialize(self.as_slice(), &mut write_buf)
249	}
250}
251
252impl<T: DeserializeBytes> DeserializeBytes for Vec<T> {
253	fn deserialize(mut read_buf: impl Buf) -> Result<Self, SerializationError>
254	where
255		Self: Sized,
256	{
257		let len: usize = DeserializeBytes::deserialize(&mut read_buf)?;
258		(0..len)
259			.map(|_| DeserializeBytes::deserialize(&mut read_buf))
260			.collect()
261	}
262}
263
264impl<T: SerializeBytes> SerializeBytes for Option<T> {
265	fn serialize(&self, mut write_buf: impl BufMut) -> Result<(), SerializationError> {
266		match self {
267			Some(value) => {
268				SerializeBytes::serialize(&true, &mut write_buf)?;
269				SerializeBytes::serialize(value, &mut write_buf)?;
270			}
271			None => {
272				SerializeBytes::serialize(&false, write_buf)?;
273			}
274		}
275		Ok(())
276	}
277}
278
279impl<T: DeserializeBytes> DeserializeBytes for Option<T> {
280	fn deserialize(mut read_buf: impl Buf) -> Result<Self, SerializationError>
281	where
282		Self: Sized,
283	{
284		Ok(match bool::deserialize(&mut read_buf)? {
285			true => Some(T::deserialize(&mut read_buf)?),
286			false => None,
287		})
288	}
289}
290
291impl<U: SerializeBytes, V: SerializeBytes> SerializeBytes for (U, V) {
292	fn serialize(&self, mut write_buf: impl BufMut) -> Result<(), SerializationError> {
293		U::serialize(&self.0, &mut write_buf)?;
294		V::serialize(&self.1, write_buf)
295	}
296}
297
298impl<U: DeserializeBytes, V: DeserializeBytes> DeserializeBytes for (U, V) {
299	fn deserialize(mut read_buf: impl Buf) -> Result<Self, SerializationError>
300	where
301		Self: Sized,
302	{
303		Ok((U::deserialize(&mut read_buf)?, V::deserialize(read_buf)?))
304	}
305}
306
307impl<T: SerializeBytes, const N: usize> SerializeBytes for [T; N] {
308	fn serialize(&self, mut write_buf: impl BufMut) -> Result<(), SerializationError> {
309		for val in self {
310			val.serialize(&mut write_buf)?;
311		}
312		Ok(())
313	}
314}
315
316impl<T: DeserializeBytes, const N: usize> DeserializeBytes for [T; N] {
317	fn deserialize(mut read_buf: impl Buf) -> Result<Self, SerializationError>
318	where
319		Self: Sized,
320	{
321		array_util::try_from_fn(|_| T::deserialize(&mut read_buf))
322	}
323}
324
325impl<U: ArraySize> SerializeBytes for Array<u8, U> {
326	fn serialize(&self, mut write_buf: impl BufMut) -> Result<(), SerializationError> {
327		assert_enough_space_for(&write_buf, U::USIZE)?;
328		write_buf.put_slice(self);
329		Ok(())
330	}
331}
332
333impl<U: ArraySize> DeserializeBytes for Array<u8, U> {
334	fn deserialize(mut read_buf: impl Buf) -> Result<Self, SerializationError> {
335		assert_enough_data_for(&read_buf, U::USIZE)?;
336		let mut ret = Self::default();
337		read_buf.copy_to_slice(&mut ret);
338		Ok(ret)
339	}
340}
341
342#[inline]
343pub fn assert_enough_space_for(
344	write_buf: &impl BufMut,
345	size: usize,
346) -> Result<(), SerializationError> {
347	if write_buf.remaining_mut() < size {
348		return Err(SerializationError::WriteBufferFull);
349	}
350	Ok(())
351}
352
353#[inline]
354pub fn assert_enough_data_for(read_buf: &impl Buf, size: usize) -> Result<(), SerializationError> {
355	if read_buf.remaining() < size {
356		return Err(SerializationError::NotEnoughBytes);
357	}
358	Ok(())
359}
360
361#[cfg(test)]
362mod tests {
363	use hybrid_array::sizes::U32;
364	use rand::prelude::*;
365
366	use super::*;
367
368	#[test]
369	fn test_generic_array_serialize_deserialize() {
370		let mut rng = StdRng::seed_from_u64(0);
371
372		let mut data = Array::<u8, U32>::default();
373		rng.fill_bytes(&mut data);
374
375		let mut buf = Vec::new();
376		data.serialize(&mut buf).unwrap();
377
378		let data_deserialized = Array::<u8, U32>::deserialize(&mut buf.as_slice()).unwrap();
379		assert_eq!(data_deserialized, data);
380	}
381}