1#![doc = include_str!("../README.md")]
2#![deny(missing_docs, warnings)]
3#![forbid(unsafe_code)]
4#![cfg_attr(not(any(feature = "std", test)), no_std)]
5#![cfg_attr(docsrs, feature(doc_cfg))]
6#![cfg_attr(docsrs, allow(unused_attributes))]
7
8#[cfg(all(not(feature = "std"), feature = "alloc"))]
9extern crate alloc as std;
10
11#[cfg(feature = "std")]
12extern crate std;
13
14macro_rules! test_transformable {
15 ($ty: ty => $test_fn:ident($init: expr)) => {
16 #[test]
17 fn $test_fn() {
18 use crate::TestTransformable;
19
20 <$ty>::test_transformable(|| $init);
21 }
22 };
23}
24
25#[cfg(any(feature = "alloc", feature = "std"))]
26const MESSAGE_SIZE_LEN: usize = core::mem::size_of::<u32>();
27#[cfg(feature = "std")]
28const MAX_INLINED_BYTES: usize = 256;
29
30pub trait Transformable: Send + Sync + 'static {
32 type Error: core::error::Error + Send + Sync + 'static;
34
35 fn encode(&self, dst: &mut [u8]) -> Result<usize, Self::Error>;
39
40 #[cfg(any(feature = "alloc", feature = "std"))]
42 #[cfg_attr(docsrs, doc(cfg(any(feature = "alloc", feature = "std"))))]
43 fn encode_to_vec(&self) -> Result<::std::vec::Vec<u8>, Self::Error> {
44 let mut buf = ::std::vec![0u8; self.encoded_len()];
45 self.encode(&mut buf)?;
46 Ok(buf)
47 }
48
49 #[cfg(feature = "std")]
51 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
52 fn encode_to_writer<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<usize> {
53 let encoded_len = self.encoded_len();
54 if encoded_len <= MAX_INLINED_BYTES {
55 let mut buf = [0u8; MAX_INLINED_BYTES];
56 let len = self.encode(&mut buf).map_err(utils::invalid_data)?;
57 writer.write_all(&buf[..encoded_len]).map(|_| len)
58 } else {
59 let mut buf = ::std::vec![0u8; encoded_len];
60 let len = self.encode(&mut buf).map_err(utils::invalid_data)?;
61 writer.write_all(&buf).map(|_| len)
62 }
63 }
64
65 #[cfg(feature = "async")]
67 #[cfg_attr(docsrs, doc(cfg(feature = "async")))]
68 fn encode_to_async_writer<W: futures_util::io::AsyncWrite + Send + Unpin>(
69 &self,
70 writer: &mut W,
71 ) -> impl std::future::Future<Output = std::io::Result<usize>> + Send {
72 use futures_util::io::AsyncWriteExt;
73 async move {
74 let encoded_len = self.encoded_len();
75 if encoded_len <= MAX_INLINED_BYTES {
76 let mut buf = [0u8; MAX_INLINED_BYTES];
77 let len = self.encode(&mut buf).map_err(utils::invalid_data)?;
78 writer.write_all(&buf[..encoded_len]).await.map(|_| len)
79 } else {
80 let mut buf = ::std::vec![0u8; encoded_len];
81 let len = self.encode(&mut buf).map_err(utils::invalid_data)?;
82 writer.write_all(&buf).await.map(|_| len)
83 }
84 }
85 }
86
87 fn encoded_len(&self) -> usize;
90
91 fn decode(src: &[u8]) -> Result<(usize, Self), Self::Error>
95 where
96 Self: Sized;
97
98 #[cfg(feature = "std")]
102 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
103 fn decode_from_reader<R: std::io::Read>(reader: &mut R) -> std::io::Result<(usize, Self)>
104 where
105 Self: Sized,
106 {
107 use byteorder::{ByteOrder, NetworkEndian};
108
109 let mut len = [0u8; MESSAGE_SIZE_LEN];
110 reader.read_exact(&mut len)?;
111 let msg_len = NetworkEndian::read_u32(&len) as usize;
112
113 if msg_len <= MAX_INLINED_BYTES {
114 let mut buf = [0u8; MAX_INLINED_BYTES];
115 buf[..MESSAGE_SIZE_LEN].copy_from_slice(&len);
116 reader.read_exact(&mut buf[MESSAGE_SIZE_LEN..msg_len])?;
117 Self::decode(&buf[..msg_len]).map_err(utils::invalid_data)
118 } else {
119 let mut buf = ::std::vec![0u8; msg_len];
120 buf[..MESSAGE_SIZE_LEN].copy_from_slice(&len);
121 reader.read_exact(&mut buf[MESSAGE_SIZE_LEN..])?;
122 Self::decode(&buf).map_err(utils::invalid_data)
123 }
124 }
125
126 #[cfg(feature = "async")]
130 #[cfg_attr(docsrs, doc(cfg(feature = "async")))]
131 fn decode_from_async_reader<R: futures_util::io::AsyncRead + Send + Unpin>(
132 reader: &mut R,
133 ) -> impl std::future::Future<Output = std::io::Result<(usize, Self)>> + Send
134 where
135 Self: Sized,
136 {
137 use byteorder::{ByteOrder, NetworkEndian};
138 use futures_util::io::AsyncReadExt;
139
140 async move {
141 let mut len = [0u8; MESSAGE_SIZE_LEN];
142 reader.read_exact(&mut len).await?;
143 let msg_len = NetworkEndian::read_u32(&len) as usize;
144
145 if msg_len <= MAX_INLINED_BYTES {
146 let mut buf = [0u8; MAX_INLINED_BYTES];
147 buf[..MESSAGE_SIZE_LEN].copy_from_slice(&len);
148 reader
149 .read_exact(&mut buf[MESSAGE_SIZE_LEN..msg_len])
150 .await?;
151 Self::decode(&buf[..msg_len]).map_err(utils::invalid_data)
152 } else {
153 let mut buf = vec![0u8; msg_len];
154 buf[..MESSAGE_SIZE_LEN].copy_from_slice(&len);
155 reader.read_exact(&mut buf[MESSAGE_SIZE_LEN..]).await?;
156 Self::decode(&buf).map_err(utils::invalid_data)
157 }
158 }
159 }
160}
161
162pub trait Encodable: Send + Sync {
164 type Error: core::error::Error + Send + Sync + 'static;
166
167 fn encode(&self, dst: &mut [u8]) -> Result<usize, Self::Error>;
171
172 #[cfg(any(feature = "alloc", feature = "std"))]
174 #[cfg_attr(docsrs, doc(cfg(any(feature = "alloc", feature = "std"))))]
175 fn encode_to_vec(&self) -> Result<::std::vec::Vec<u8>, Self::Error> {
176 let mut buf = ::std::vec![0u8; self.encoded_len()];
177 self.encode(&mut buf)?;
178 Ok(buf)
179 }
180
181 #[cfg(feature = "std")]
183 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
184 fn encode_to_writer<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<usize> {
185 let encoded_len = self.encoded_len();
186 if encoded_len <= MAX_INLINED_BYTES {
187 let mut buf = [0u8; MAX_INLINED_BYTES];
188 let len = self.encode(&mut buf).map_err(utils::invalid_data)?;
189 writer.write_all(&buf[..encoded_len]).map(|_| len)
190 } else {
191 let mut buf = ::std::vec![0u8; encoded_len];
192 let len = self.encode(&mut buf).map_err(utils::invalid_data)?;
193 writer.write_all(&buf).map(|_| len)
194 }
195 }
196
197 #[cfg(feature = "async")]
199 #[cfg_attr(docsrs, doc(cfg(feature = "async")))]
200 fn encode_to_async_writer<W: futures_util::io::AsyncWrite + Send + Unpin>(
201 &self,
202 writer: &mut W,
203 ) -> impl std::future::Future<Output = std::io::Result<usize>> + Send {
204 use futures_util::io::AsyncWriteExt;
205 async move {
206 let encoded_len = self.encoded_len();
207 if encoded_len <= MAX_INLINED_BYTES {
208 let mut buf = [0u8; MAX_INLINED_BYTES];
209 let len = self.encode(&mut buf).map_err(utils::invalid_data)?;
210 writer.write_all(&buf[..encoded_len]).await.map(|_| len)
211 } else {
212 let mut buf = ::std::vec![0u8; encoded_len];
213 let len = self.encode(&mut buf).map_err(utils::invalid_data)?;
214 writer.write_all(&buf).await.map(|_| len)
215 }
216 }
217 }
218
219 fn encoded_len(&self) -> usize;
222}
223
224impl<T: Transformable> Encodable for T {
225 type Error = T::Error;
226
227 fn encode(&self, dst: &mut [u8]) -> Result<usize, Self::Error> {
228 Transformable::encode(self, dst)
229 }
230
231 fn encoded_len(&self) -> usize {
232 Transformable::encoded_len(self)
233 }
234
235 #[cfg(any(feature = "alloc", feature = "std"))]
236 fn encode_to_vec(&self) -> Result<::std::vec::Vec<u8>, Self::Error> {
237 Transformable::encode_to_vec(self)
238 }
239
240 #[cfg(feature = "std")]
241 fn encode_to_writer<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<usize> {
242 Transformable::encode_to_writer(self, writer)
243 }
244
245 #[cfg(feature = "async")]
246 fn encode_to_async_writer<W: futures_util::io::AsyncWrite + Send + Unpin>(
247 &self,
248 writer: &mut W,
249 ) -> impl std::future::Future<Output = std::io::Result<usize>> + Send {
250 Transformable::encode_to_async_writer(self, writer)
251 }
252}
253
254pub trait Decodable: Send + 'static {
256 type Error: core::error::Error + Send + Sync + 'static;
258
259 fn decode(src: &[u8]) -> Result<(usize, Self), Self::Error>
263 where
264 Self: Sized;
265
266 #[cfg(feature = "std")]
270 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
271 fn decode_from_reader<R: std::io::Read>(reader: &mut R) -> std::io::Result<(usize, Self)>
272 where
273 Self: Sized;
274
275 #[cfg(feature = "async")]
279 #[cfg_attr(docsrs, doc(cfg(feature = "async")))]
280 fn decode_from_async_reader<R: futures_util::io::AsyncRead + Send + Unpin>(
281 reader: &mut R,
282 ) -> impl std::future::Future<Output = std::io::Result<(usize, Self)>> + Send
283 where
284 Self: Sized;
285}
286
287impl<T: Transformable> Decodable for T {
288 type Error = T::Error;
289
290 fn decode(src: &[u8]) -> Result<(usize, Self), Self::Error> {
291 Transformable::decode(src)
292 }
293
294 #[cfg(feature = "std")]
295 fn decode_from_reader<R: std::io::Read>(reader: &mut R) -> std::io::Result<(usize, Self)>
296 where
297 Self: Sized,
298 {
299 Transformable::decode_from_reader(reader)
300 }
301
302 #[cfg(feature = "async")]
303 fn decode_from_async_reader<R: futures_util::io::AsyncRead + Send + Unpin>(
304 reader: &mut R,
305 ) -> impl std::future::Future<Output = std::io::Result<(usize, Self)>> + Send
306 where
307 Self: Sized + Send,
308 {
309 <Self as Transformable>::decode_from_async_reader::<R>(reader)
310 }
311}
312
313#[cfg(test)]
314trait TestTransformable: Transformable + Eq + core::fmt::Debug + Sized {
315 fn test_transformable(init: impl FnOnce() -> Self)
316 where
317 <Self as Transformable>::Error: core::error::Error + Send + Sync + 'static,
318 {
319 let val = init();
320 let mut buf = std::vec![0; val.encoded_len()];
321 val.encode(&mut buf).unwrap();
322 let (_, decoded) = Self::decode(&buf).unwrap();
323 assert_eq!(decoded, val);
324
325 #[cfg(feature = "std")]
326 {
327 let mut buf = std::vec::Vec::new();
328 val.encode_to_writer(&mut buf).unwrap();
329 let (_, decoded) = Self::decode_from_reader(&mut buf.as_slice()).unwrap();
330 assert_eq!(decoded, val);
331 }
332 }
333}
334
335#[cfg(test)]
336impl<T: Transformable + Eq + core::fmt::Debug + Sized> TestTransformable for T {}
337
338mod impls;
339pub use impls::*;
340
341pub mod utils;