binius_utils/
serialization.rs

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