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("FromUtf8Error: {0}")]
53	FromUtf8Error(#[from] std::string::FromUtf8Error),
54	#[error("Invalid construction of {name}")]
55	InvalidConstruction { name: &'static str },
56	#[error("usize {size} is too large to serialize (max is {max})", max = u32::MAX)]
57	UsizeTooLarge { size: usize },
58}
59
60impl<T: SerializeBytes + ?Sized> SerializeBytes for &T {
61	fn serialize(&self, write_buf: impl BufMut) -> Result<(), SerializationError> {
62		(**self).serialize(write_buf)
63	}
64}
65
66impl SerializeBytes for usize {
67	fn serialize(&self, mut write_buf: impl BufMut) -> Result<(), SerializationError> {
68		let value: u32 = (*self)
69			.try_into()
70			.map_err(|_| SerializationError::UsizeTooLarge { size: *self })?;
71		SerializeBytes::serialize(&value, &mut write_buf)
72	}
73}
74
75impl DeserializeBytes for usize {
76	fn deserialize(mut read_buf: impl Buf) -> Result<Self, SerializationError>
77	where
78		Self: Sized,
79	{
80		let value: u32 = DeserializeBytes::deserialize(&mut read_buf)?;
81		Ok(value as Self)
82	}
83}
84
85impl SerializeBytes for u128 {
86	fn serialize(&self, mut write_buf: impl BufMut) -> Result<(), SerializationError> {
87		assert_enough_space_for(&write_buf, std::mem::size_of::<Self>())?;
88		write_buf.put_u128_le(*self);
89		Ok(())
90	}
91}
92
93impl DeserializeBytes for u128 {
94	fn deserialize(mut read_buf: impl Buf) -> Result<Self, SerializationError>
95	where
96		Self: Sized,
97	{
98		assert_enough_data_for(&read_buf, std::mem::size_of::<Self>())?;
99		Ok(read_buf.get_u128_le())
100	}
101}
102
103impl SerializeBytes for u64 {
104	fn serialize(&self, mut write_buf: impl BufMut) -> Result<(), SerializationError> {
105		assert_enough_space_for(&write_buf, std::mem::size_of::<Self>())?;
106		write_buf.put_u64_le(*self);
107		Ok(())
108	}
109}
110
111impl DeserializeBytes for u64 {
112	fn deserialize(mut read_buf: impl Buf) -> Result<Self, SerializationError>
113	where
114		Self: Sized,
115	{
116		assert_enough_data_for(&read_buf, std::mem::size_of::<Self>())?;
117		Ok(read_buf.get_u64_le())
118	}
119}
120
121impl SerializeBytes for u32 {
122	fn serialize(&self, mut write_buf: impl BufMut) -> Result<(), SerializationError> {
123		assert_enough_space_for(&write_buf, std::mem::size_of::<Self>())?;
124		write_buf.put_u32_le(*self);
125		Ok(())
126	}
127}
128
129impl DeserializeBytes for u32 {
130	fn deserialize(mut read_buf: impl Buf) -> Result<Self, SerializationError>
131	where
132		Self: Sized,
133	{
134		assert_enough_data_for(&read_buf, std::mem::size_of::<Self>())?;
135		Ok(read_buf.get_u32_le())
136	}
137}
138
139impl SerializeBytes for u16 {
140	fn serialize(&self, mut write_buf: impl BufMut) -> Result<(), SerializationError> {
141		assert_enough_space_for(&write_buf, std::mem::size_of::<Self>())?;
142		write_buf.put_u16_le(*self);
143		Ok(())
144	}
145}
146
147impl DeserializeBytes for u16 {
148	fn deserialize(mut read_buf: impl Buf) -> Result<Self, SerializationError>
149	where
150		Self: Sized,
151	{
152		assert_enough_data_for(&read_buf, std::mem::size_of::<Self>())?;
153		Ok(read_buf.get_u16_le())
154	}
155}
156
157impl SerializeBytes for u8 {
158	fn serialize(&self, mut write_buf: impl BufMut) -> Result<(), SerializationError> {
159		assert_enough_space_for(&write_buf, std::mem::size_of::<Self>())?;
160		write_buf.put_u8(*self);
161		Ok(())
162	}
163}
164
165impl DeserializeBytes for u8 {
166	fn deserialize(mut read_buf: impl Buf) -> Result<Self, SerializationError>
167	where
168		Self: Sized,
169	{
170		assert_enough_data_for(&read_buf, std::mem::size_of::<Self>())?;
171		Ok(read_buf.get_u8())
172	}
173}
174
175impl SerializeBytes for bool {
176	fn serialize(&self, write_buf: impl BufMut) -> Result<(), SerializationError> {
177		u8::serialize(&(*self as u8), write_buf)
178	}
179}
180
181impl DeserializeBytes for bool {
182	fn deserialize(read_buf: impl Buf) -> Result<Self, SerializationError>
183	where
184		Self: Sized,
185	{
186		Ok(u8::deserialize(read_buf)? != 0)
187	}
188}
189
190impl<T> SerializeBytes for std::marker::PhantomData<T> {
191	fn serialize(&self, _write_buf: impl BufMut) -> Result<(), SerializationError> {
192		Ok(())
193	}
194}
195
196impl<T> DeserializeBytes for std::marker::PhantomData<T> {
197	fn deserialize(_read_buf: impl Buf) -> Result<Self, SerializationError>
198	where
199		Self: Sized,
200	{
201		Ok(Self)
202	}
203}
204
205impl SerializeBytes for &str {
206	fn serialize(&self, mut write_buf: impl BufMut) -> Result<(), SerializationError> {
207		let bytes = self.as_bytes();
208		SerializeBytes::serialize(&bytes.len(), &mut write_buf)?;
209		assert_enough_space_for(&write_buf, bytes.len())?;
210		write_buf.put_slice(bytes);
211		Ok(())
212	}
213}
214
215impl SerializeBytes for String {
216	fn serialize(&self, mut write_buf: impl BufMut) -> Result<(), SerializationError> {
217		SerializeBytes::serialize(&self.as_str(), &mut write_buf)
218	}
219}
220
221impl DeserializeBytes for String {
222	fn deserialize(mut read_buf: impl Buf) -> Result<Self, SerializationError>
223	where
224		Self: Sized,
225	{
226		let len = DeserializeBytes::deserialize(&mut read_buf)?;
227		assert_enough_data_for(&read_buf, len)?;
228		Ok(Self::from_utf8(read_buf.copy_to_bytes(len).to_vec())?)
229	}
230}
231
232impl<T: SerializeBytes> SerializeBytes for [T] {
233	fn serialize(&self, mut write_buf: impl BufMut) -> Result<(), SerializationError> {
234		SerializeBytes::serialize(&self.len(), &mut write_buf)?;
235		self.iter()
236			.try_for_each(|item| SerializeBytes::serialize(item, &mut write_buf))
237	}
238}
239
240impl<T: SerializeBytes> SerializeBytes for Vec<T> {
241	fn serialize(&self, mut write_buf: impl BufMut) -> Result<(), SerializationError> {
242		SerializeBytes::serialize(self.as_slice(), &mut write_buf)
243	}
244}
245
246impl<T: DeserializeBytes> DeserializeBytes for Vec<T> {
247	fn deserialize(mut read_buf: impl Buf) -> Result<Self, SerializationError>
248	where
249		Self: Sized,
250	{
251		let len: usize = DeserializeBytes::deserialize(&mut read_buf)?;
252		(0..len)
253			.map(|_| DeserializeBytes::deserialize(&mut read_buf))
254			.collect()
255	}
256}
257
258impl<T: SerializeBytes> SerializeBytes for Option<T> {
259	fn serialize(&self, mut write_buf: impl BufMut) -> Result<(), SerializationError> {
260		match self {
261			Some(value) => {
262				SerializeBytes::serialize(&true, &mut write_buf)?;
263				SerializeBytes::serialize(value, &mut write_buf)?;
264			}
265			None => {
266				SerializeBytes::serialize(&false, write_buf)?;
267			}
268		}
269		Ok(())
270	}
271}
272
273impl<T: DeserializeBytes> DeserializeBytes for Option<T> {
274	fn deserialize(mut read_buf: impl Buf) -> Result<Self, SerializationError>
275	where
276		Self: Sized,
277	{
278		Ok(if bool::deserialize(&mut read_buf)? {
279			Some(T::deserialize(&mut read_buf)?)
280		} else {
281			None
282		})
283	}
284}
285
286impl<U: SerializeBytes, V: SerializeBytes> SerializeBytes for (U, V) {
287	fn serialize(&self, mut write_buf: impl BufMut) -> Result<(), SerializationError> {
288		U::serialize(&self.0, &mut write_buf)?;
289		V::serialize(&self.1, write_buf)
290	}
291}
292
293impl<U: DeserializeBytes, V: DeserializeBytes> DeserializeBytes for (U, V) {
294	fn deserialize(mut read_buf: impl Buf) -> Result<Self, SerializationError>
295	where
296		Self: Sized,
297	{
298		Ok((U::deserialize(&mut read_buf)?, V::deserialize(read_buf)?))
299	}
300}
301
302impl<T: SerializeBytes, const N: usize> SerializeBytes for [T; N] {
303	fn serialize(&self, mut write_buf: impl BufMut) -> Result<(), SerializationError> {
304		for val in self {
305			val.serialize(&mut write_buf)?;
306		}
307		Ok(())
308	}
309}
310
311impl<T: DeserializeBytes, const N: usize> DeserializeBytes for [T; N] {
312	fn deserialize(mut read_buf: impl Buf) -> Result<Self, SerializationError>
313	where
314		Self: Sized,
315	{
316		array_util::try_from_fn(|_| T::deserialize(&mut read_buf))
317	}
318}
319
320impl<U: ArraySize> SerializeBytes for Array<u8, U> {
321	fn serialize(&self, mut write_buf: impl BufMut) -> Result<(), SerializationError> {
322		assert_enough_space_for(&write_buf, U::USIZE)?;
323		write_buf.put_slice(self);
324		Ok(())
325	}
326}
327
328impl<U: ArraySize> DeserializeBytes for Array<u8, U> {
329	fn deserialize(mut read_buf: impl Buf) -> Result<Self, SerializationError> {
330		assert_enough_data_for(&read_buf, U::USIZE)?;
331		let mut ret = Self::default();
332		read_buf.copy_to_slice(&mut ret);
333		Ok(ret)
334	}
335}
336
337#[inline]
338pub fn assert_enough_space_for(
339	write_buf: &impl BufMut,
340	size: usize,
341) -> Result<(), SerializationError> {
342	if write_buf.remaining_mut() < size {
343		return Err(SerializationError::WriteBufferFull);
344	}
345	Ok(())
346}
347
348#[inline]
349pub fn assert_enough_data_for(read_buf: &impl Buf, size: usize) -> Result<(), SerializationError> {
350	if read_buf.remaining() < size {
351		return Err(SerializationError::NotEnoughBytes);
352	}
353	Ok(())
354}
355
356#[cfg(test)]
357mod tests {
358	use hybrid_array::sizes::U32;
359	use rand::prelude::*;
360
361	use super::*;
362
363	#[test]
364	fn test_generic_array_serialize_deserialize() {
365		let mut rng = StdRng::seed_from_u64(0);
366
367		let mut data = Array::<u8, U32>::default();
368		rng.fill_bytes(&mut data);
369
370		let mut buf = Vec::new();
371		data.serialize(&mut buf).unwrap();
372
373		let data_deserialized = Array::<u8, U32>::deserialize(&mut buf.as_slice()).unwrap();
374		assert_eq!(data_deserialized, data);
375	}
376}