channels_serdes/
lib.rs

1//! Utilities to serialize/deserialize types.
2//!
3//! # Implementing a serializer/deserializer
4//!
5//! ```rust
6//! use std::convert::Infallible;
7//! use channels_serdes::{Serializer, Deserializer};
8//!
9//! struct MyI32;
10//!
11//! #[derive(Debug, PartialEq, Eq)]
12//! enum I32DeserializeError {
13//!     NotEnough,
14//! }
15//!
16//! impl Serializer<i32> for MyI32 {
17//!     type Error = Infallible; // serializing an i32 cannot fail
18//!
19//!     fn serialize(&mut self, t: &i32) -> Result<Vec<u8>, Self::Error> {
20//!         let vec = t.to_be_bytes().to_vec();
21//!         Ok(vec)
22//!     }
23//! }
24//!
25//! impl Deserializer<i32> for MyI32 {
26//!     type Error = I32DeserializeError;
27//!
28//!     fn deserialize(&mut self, buf: &mut [u8]) -> Result<i32, Self::Error> {
29//!         buf.get(..4)
30//!            .map(|slice| -> [u8; 4] { slice.try_into().unwrap() })
31//!            .map(i32::from_be_bytes)
32//!            .ok_or(I32DeserializeError::NotEnough)
33//!     }
34//! }
35//!
36//! let mut sd = MyI32;
37//!
38//! let mut serialized: Vec<u8> = sd.serialize(&42).unwrap();
39//! assert_eq!(serialized, [0, 0, 0, 42]);
40//!
41//! let deserialized = sd.deserialize(&mut serialized[..]);
42//! assert_eq!(deserialized, Ok(42));
43//! ```
44#![cfg_attr(channels_nightly, feature(doc_auto_cfg))]
45#![cfg_attr(not(feature = "std"), no_std)]
46
47extern crate alloc;
48
49use alloc::vec::Vec;
50
51/// The [`Serializer`] trait allows converting a type `T` to safe-to-transport
52/// byte sequences.
53///
54/// Types implementing this trait are called 'serializers'.
55pub trait Serializer<T> {
56	/// The error returned by [`Serializer::serialize()`].
57	type Error;
58
59	/// Serialize `t` to a buffer.
60	fn serialize(&mut self, t: &T) -> Result<Vec<u8>, Self::Error>;
61}
62
63macro_rules! forward_serializer_impl {
64	($to:ty) => {
65		type Error = <$to>::Error;
66
67		fn serialize(
68			&mut self,
69			t: &T,
70		) -> Result<Vec<u8>, Self::Error> {
71			<$to>::serialize(self, t)
72		}
73	};
74}
75
76/// The [`Deserializer`] trait allows converting a byte slice to a type `T`.
77///
78/// Types implementing this trait are called 'deserializers'.
79pub trait Deserializer<T> {
80	/// The error returned by [`Deserializer::deserialize()`].
81	type Error;
82
83	/// Deserialize bytes from `buf` to a type `T`.
84	///
85	/// Implementations can freely modify `buf` if needed.
86	fn deserialize(
87		&mut self,
88		buf: &mut [u8],
89	) -> Result<T, Self::Error>;
90}
91
92macro_rules! forward_deserializer_impl {
93	($to:ty) => {
94		type Error = <$to>::Error;
95
96		fn deserialize(
97			&mut self,
98			buf: &mut [u8],
99		) -> Result<T, Self::Error> {
100			<$to>::deserialize(self, buf)
101		}
102	};
103}
104
105impl<T, U: Serializer<T> + ?Sized> Serializer<T> for &mut U {
106	forward_serializer_impl!(U);
107}
108
109impl<T, U: Deserializer<T> + ?Sized> Deserializer<T> for &mut U {
110	forward_deserializer_impl!(U);
111}
112
113#[cfg(feature = "alloc")]
114impl<T, U: Serializer<T> + ?Sized> Serializer<T>
115	for alloc::boxed::Box<U>
116{
117	forward_serializer_impl!(U);
118}
119
120#[cfg(feature = "alloc")]
121impl<T, U: Deserializer<T> + ?Sized> Deserializer<T>
122	for alloc::boxed::Box<U>
123{
124	forward_deserializer_impl!(U);
125}
126
127macro_rules! serdes_impl {
128	($module:ident :: $impl:ident if $($cfg:tt)+) => {
129		#[cfg($($cfg)+)]
130		pub mod $module;
131		#[cfg($($cfg)+)]
132		pub use self::$module::$impl;
133	};
134}
135
136#[cfg(feature = "aead")]
137pub mod aead;
138
139serdes_impl! { bincode::Bincode if feature = "bincode" }
140serdes_impl! { cbor::Cbor       if feature = "cbor"    }
141serdes_impl! { json::Json       if feature = "json"    }
142serdes_impl! { borsh::Borsh     if feature = "borsh"   }
143serdes_impl! { crc::Crc         if feature = "crc"     }
144serdes_impl! { deflate::Deflate if feature = "deflate" }
145serdes_impl! { hmac::Hmac       if feature = "hmac"    }