1#[doc(hidden)]
2pub mod macro_helpers;
3pub mod serde_self_describing;
4
5use std::{any::Any, ptr::copy_nonoverlapping};
6
7use ::smallvec::SmallVec;
8use bincode::{
9 BorrowDecode, Decode, Encode,
10 de::{BorrowDecoder, Decoder, DecoderImpl, read::Reader},
11 enc::{Encoder, EncoderImpl, write::Writer},
12 error::{DecodeError, EncodeError},
13};
14
15pub const TURBO_BINCODE_CONFIG: bincode::config::Configuration = bincode::config::standard();
16pub type TurboBincodeBuffer = SmallVec<[u8; 16]>;
17pub type TurboBincodeEncoder<'a> =
18 EncoderImpl<TurboBincodeWriter<'a>, bincode::config::Configuration>;
19pub type TurboBincodeDecoder<'a> =
20 DecoderImpl<TurboBincodeReader<'a>, bincode::config::Configuration, ()>;
21pub type AnyEncodeFn = fn(&dyn Any, &mut TurboBincodeEncoder<'_>) -> Result<(), EncodeError>;
22pub type AnyDecodeFn<T> = fn(&mut TurboBincodeDecoder<'_>) -> Result<T, DecodeError>;
23
24fn new_turbo_bincode_encoder(buf: &mut TurboBincodeBuffer) -> TurboBincodeEncoder<'_> {
25 EncoderImpl::new(TurboBincodeWriter::new(buf), TURBO_BINCODE_CONFIG)
26}
27
28fn new_turbo_bincode_decoder(buffer: &[u8]) -> TurboBincodeDecoder<'_> {
29 DecoderImpl::new(TurboBincodeReader::new(buffer), TURBO_BINCODE_CONFIG, ())
30}
31
32pub fn turbo_bincode_encode<T: Encode>(value: &T) -> Result<TurboBincodeBuffer, EncodeError> {
37 let mut buffer = TurboBincodeBuffer::new();
38 turbo_bincode_encode_into(value, &mut buffer)?;
39 Ok(buffer)
40}
41
42pub fn turbo_bincode_encode_into<T: Encode>(
43 value: &T,
44 buffer: &mut TurboBincodeBuffer,
45) -> Result<(), EncodeError> {
46 let mut encoder = new_turbo_bincode_encoder(buffer);
47 value.encode(&mut encoder)?;
48 Ok(())
49}
50
51pub fn turbo_bincode_decode<T: Decode<()>>(buf: &[u8]) -> Result<T, DecodeError> {
54 let mut decoder = new_turbo_bincode_decoder(buf);
55 let val = T::decode(&mut decoder)?;
56 let remaining_buf = decoder.reader().buffer;
57 if !remaining_buf.is_empty() {
58 return Err(DecodeError::ArrayLengthMismatch {
59 required: buf.len() - remaining_buf.len(),
60 found: buf.len(),
61 });
62 }
63 Ok(val)
64}
65
66pub struct TurboBincodeWriter<'a> {
67 pub buffer: &'a mut TurboBincodeBuffer,
68}
69
70impl<'a> TurboBincodeWriter<'a> {
71 pub fn new(buffer: &'a mut TurboBincodeBuffer) -> Self {
72 Self { buffer }
73 }
74}
75
76impl Writer for TurboBincodeWriter<'_> {
77 fn write(&mut self, bytes: &[u8]) -> Result<(), EncodeError> {
78 self.buffer.extend_from_slice(bytes);
79 Ok(())
80 }
81}
82
83pub struct TurboBincodeReader<'a> {
86 pub buffer: &'a [u8],
87}
88
89impl<'a> TurboBincodeReader<'a> {
90 pub fn new(buffer: &'a [u8]) -> Self {
91 Self { buffer }
92 }
93}
94
95impl Reader for TurboBincodeReader<'_> {
96 fn read(&mut self, target_buffer: &mut [u8]) -> Result<(), DecodeError> {
97 let len = target_buffer.len();
98 let (head, rest) =
99 self.buffer
100 .split_at_checked(len)
101 .ok_or_else(|| DecodeError::UnexpectedEnd {
102 additional: len - self.buffer.len(),
103 })?;
104 unsafe {
109 copy_nonoverlapping(head.as_ptr(), target_buffer.as_mut_ptr(), len);
110 }
111 self.buffer = rest;
112 Ok(())
113 }
114
115 fn peek_read(&mut self, n: usize) -> Option<&[u8]> {
116 self.buffer.get(..n)
117 }
118
119 fn consume(&mut self, n: usize) {
120 self.buffer = &self.buffer[n..];
121 }
122}
123
124pub trait TurboBincodeEncode: Encode {
132 fn encode(&self, encoder: &mut TurboBincodeEncoder) -> Result<(), EncodeError>;
133}
134
135pub trait TurboBincodeDecode<Context>: Decode<Context> {
144 fn decode(decoder: &mut TurboBincodeDecoder) -> Result<Self, DecodeError>;
145}
146
147#[macro_export]
148macro_rules! impl_encode_for_turbo_bincode_encode {
149 ($ty:ty) => {
150 impl $crate::macro_helpers::bincode::Encode for $ty {
151 fn encode<'a, E: $crate::macro_helpers::bincode::enc::Encoder>(
152 &self,
153 encoder: &'a mut E,
154 ) -> ::std::result::Result<(), $crate::macro_helpers::bincode::error::EncodeError> {
155 $crate::macro_helpers::encode_for_turbo_bincode_encode_impl(self, encoder)
156 }
157 }
158 };
159}
160
161#[macro_export]
162macro_rules! impl_decode_for_turbo_bincode_decode {
163 ($ty:ty) => {
164 impl<Context> $crate::macro_helpers::bincode::Decode<Context> for $ty {
165 fn decode<D: $crate::macro_helpers::bincode::de::Decoder<Context = Context>>(
166 decoder: &mut D,
167 ) -> ::std::result::Result<Self, $crate::macro_helpers::bincode::error::DecodeError>
168 {
169 $crate::macro_helpers::decode_for_turbo_bincode_decode_impl(decoder)
170 }
171 }
172 };
173}
174
175pub mod indexmap {
176 use std::hash::{BuildHasher, Hash};
177
178 use ::indexmap::IndexMap;
179
180 use super::*;
181
182 pub fn encode<E, K, V, S>(map: &IndexMap<K, V, S>, encoder: &mut E) -> Result<(), EncodeError>
183 where
184 E: Encoder,
185 K: Encode,
186 V: Encode,
187 {
188 usize::encode(&map.len(), encoder)?;
189 for (k, v) in map {
190 K::encode(k, encoder)?;
191 V::encode(v, encoder)?;
192 }
193 Ok(())
194 }
195
196 pub fn decode<Context, D, K, V, S>(decoder: &mut D) -> Result<IndexMap<K, V, S>, DecodeError>
197 where
198 D: Decoder<Context = Context>,
199 K: Decode<Context> + Eq + Hash,
200 V: Decode<Context>,
201 S: BuildHasher + Default,
202 {
203 let len = usize::decode(decoder)?;
204 let mut map = IndexMap::with_capacity_and_hasher(len, Default::default());
205 for _i in 0..len {
206 map.insert(K::decode(decoder)?, V::decode(decoder)?);
207 }
208 Ok(map)
209 }
210
211 pub fn borrow_decode<'de, Context, D, K, V, S>(
212 decoder: &mut D,
213 ) -> Result<IndexMap<K, V, S>, DecodeError>
214 where
215 D: BorrowDecoder<'de, Context = Context>,
216 K: BorrowDecode<'de, Context> + Eq + Hash,
217 V: BorrowDecode<'de, Context>,
218 S: BuildHasher + Default,
219 {
220 let len = usize::decode(decoder)?;
221 let mut map = IndexMap::with_capacity_and_hasher(len, Default::default());
222 for _i in 0..len {
223 map.insert(K::borrow_decode(decoder)?, V::borrow_decode(decoder)?);
224 }
225 Ok(map)
226 }
227
228 #[cfg(test)]
229 mod tests {
230 use bincode::{decode_from_slice, encode_to_vec};
231
232 use super::*;
233
234 #[test]
235 fn test_roundtrip() {
236 let cfg = bincode::config::standard();
237
238 #[derive(Encode, Decode)]
239 struct Wrapper(#[bincode(with = "crate::indexmap")] IndexMap<String, u32>);
240
241 let map1 = Wrapper(IndexMap::from([
242 ("key1".to_string(), 12345u32),
243 ("key2".to_string(), 23456u32),
244 ]));
245
246 let map2: Wrapper = decode_from_slice(&encode_to_vec(&map1, cfg).unwrap(), cfg)
247 .unwrap()
248 .0;
249
250 assert_eq!(map1.0, map2.0);
251 }
252 }
253}
254
255pub mod indexset {
256 use std::hash::{BuildHasher, Hash};
257
258 use ::indexmap::IndexSet;
259
260 use super::*;
261
262 pub fn encode<E, T, S>(set: &IndexSet<T, S>, encoder: &mut E) -> Result<(), EncodeError>
263 where
264 E: Encoder,
265 T: Encode,
266 {
267 usize::encode(&set.len(), encoder)?;
268 for item in set {
269 T::encode(item, encoder)?;
270 }
271 Ok(())
272 }
273
274 pub fn decode<Context, D, T, S>(decoder: &mut D) -> Result<IndexSet<T, S>, DecodeError>
275 where
276 D: Decoder<Context = Context>,
277 T: Decode<Context> + Eq + Hash,
278 S: BuildHasher + Default,
279 {
280 let len = usize::decode(decoder)?;
281 let mut set = IndexSet::with_capacity_and_hasher(len, Default::default());
282 for _i in 0..len {
283 set.insert(T::decode(decoder)?);
284 }
285 Ok(set)
286 }
287
288 pub fn borrow_decode<'de, Context, D, T, S>(
289 decoder: &mut D,
290 ) -> Result<IndexSet<T, S>, DecodeError>
291 where
292 D: BorrowDecoder<'de, Context = Context>,
293 T: BorrowDecode<'de, Context> + Eq + Hash,
294 S: BuildHasher + Default,
295 {
296 let len = usize::decode(decoder)?;
297 let mut set = IndexSet::with_capacity_and_hasher(len, Default::default());
298 for _i in 0..len {
299 set.insert(T::borrow_decode(decoder)?);
300 }
301 Ok(set)
302 }
303
304 #[cfg(test)]
305 mod tests {
306 use bincode::{decode_from_slice, encode_to_vec};
307
308 use super::*;
309
310 #[test]
311 fn test_roundtrip() {
312 let cfg = bincode::config::standard();
313
314 #[derive(Encode, Decode)]
315 struct Wrapper(#[bincode(with = "crate::indexset")] IndexSet<String>);
316
317 let set1 = Wrapper(IndexSet::from([
318 "value1".to_string(),
319 "value2".to_string(),
320 "value3".to_string(),
321 ]));
322
323 let set2: Wrapper = decode_from_slice(&encode_to_vec(&set1, cfg).unwrap(), cfg)
324 .unwrap()
325 .0;
326
327 assert_eq!(set1.0, set2.0);
328 }
329 }
330}
331
332pub mod ringset {
333 use std::hash::{BuildHasher, Hash};
334
335 use ::ringmap::RingSet;
336
337 use super::*;
338
339 pub fn encode<E, T, S>(set: &RingSet<T, S>, encoder: &mut E) -> Result<(), EncodeError>
340 where
341 E: Encoder,
342 T: Encode,
343 {
344 usize::encode(&set.len(), encoder)?;
345 for item in set {
346 T::encode(item, encoder)?;
347 }
348 Ok(())
349 }
350
351 pub fn decode<Context, D, T, S>(decoder: &mut D) -> Result<RingSet<T, S>, DecodeError>
352 where
353 D: Decoder<Context = Context>,
354 T: Decode<Context> + Eq + Hash,
355 S: BuildHasher + Default,
356 {
357 let len = usize::decode(decoder)?;
358 let mut set = RingSet::with_capacity_and_hasher(len, Default::default());
359 for _i in 0..len {
360 set.insert(T::decode(decoder)?);
361 }
362 Ok(set)
363 }
364
365 pub fn borrow_decode<'de, Context, D, T, S>(
366 decoder: &mut D,
367 ) -> Result<RingSet<T, S>, DecodeError>
368 where
369 D: BorrowDecoder<'de, Context = Context>,
370 T: BorrowDecode<'de, Context> + Eq + Hash,
371 S: BuildHasher + Default,
372 {
373 let len = usize::decode(decoder)?;
374 let mut set = RingSet::with_capacity_and_hasher(len, Default::default());
375 for _i in 0..len {
376 set.insert(T::borrow_decode(decoder)?);
377 }
378 Ok(set)
379 }
380
381 #[cfg(test)]
382 mod tests {
383 use bincode::{decode_from_slice, encode_to_vec};
384
385 use super::*;
386
387 #[test]
388 fn test_roundtrip() {
389 let cfg = bincode::config::standard();
390
391 #[derive(Encode, Decode)]
392 struct Wrapper(#[bincode(with = "crate::ringset")] RingSet<String>);
393
394 let set1 = Wrapper(RingSet::from([
395 "value1".to_string(),
396 "value2".to_string(),
397 "value3".to_string(),
398 ]));
399
400 let set2: Wrapper = decode_from_slice(&encode_to_vec(&set1, cfg).unwrap(), cfg)
401 .unwrap()
402 .0;
403
404 assert_eq!(set1.0, set2.0);
405 }
406 }
407}
408
409pub mod mime_option {
410 use std::str::FromStr;
411
412 use mime::Mime;
413
414 use super::*;
415
416 pub fn encode<E: Encoder>(mime: &Option<Mime>, encoder: &mut E) -> Result<(), EncodeError> {
417 let mime_str: Option<&str> = mime.as_ref().map(AsRef::as_ref);
418 Encode::encode(&mime_str, encoder)
419 }
420
421 pub fn decode<Context, D: Decoder<Context = Context>>(
422 decoder: &mut D,
423 ) -> Result<Option<Mime>, DecodeError> {
424 if let Some(mime_str) = <Option<String> as Decode<Context>>::decode(decoder)? {
425 Ok(Some(
426 Mime::from_str(&mime_str).map_err(|e| DecodeError::OtherString(e.to_string()))?,
427 ))
428 } else {
429 Ok(None)
430 }
431 }
432
433 pub fn borrow_decode<'de, Context, D: BorrowDecoder<'de, Context = Context>>(
434 decoder: &mut D,
435 ) -> Result<Option<Mime>, DecodeError> {
436 decode(decoder)
437 }
438
439 #[cfg(test)]
440 mod tests {
441 use bincode::{decode_from_slice, encode_to_vec};
442
443 use super::*;
444
445 #[derive(Encode, Decode)]
446 struct Wrapper(#[bincode(with = "crate::mime_option")] Option<Mime>);
447
448 #[test]
449 fn test_roundtrip() {
450 let cfg = bincode::config::standard();
451
452 let mime1 = Wrapper(Some("text/html; charset=utf-8".parse().unwrap()));
453
454 let mime2: Wrapper = decode_from_slice(&encode_to_vec(&mime1, cfg).unwrap(), cfg)
455 .unwrap()
456 .0;
457
458 assert_eq!(mime1.0, mime2.0);
459 }
460
461 #[test]
462 fn test_roundtrip_none() {
463 let cfg = bincode::config::standard();
464
465 let mime1 = Wrapper(None);
466
467 let mime2: Wrapper = decode_from_slice(&encode_to_vec(&mime1, cfg).unwrap(), cfg)
468 .unwrap()
469 .0;
470
471 assert_eq!(mime1.0, mime2.0);
472 }
473 }
474}
475
476pub mod either {
477 use ::either::Either;
478
479 use super::*;
480
481 pub fn encode<E: Encoder, L: Encode, R: Encode>(
482 value: &Either<L, R>,
483 encoder: &mut E,
484 ) -> Result<(), EncodeError> {
485 value.is_left().encode(encoder)?;
486 ::either::for_both!(value, v => Encode::encode(v, encoder))
487 }
488
489 pub fn decode<
490 Context,
491 D: Decoder<Context = Context>,
492 L: Decode<Context>,
493 R: Decode<Context>,
494 >(
495 decoder: &mut D,
496 ) -> Result<Either<L, R>, DecodeError> {
497 let is_left = bool::decode(decoder)?;
498 Ok(if is_left {
499 Either::Left(L::decode(decoder)?)
500 } else {
501 Either::Right(R::decode(decoder)?)
502 })
503 }
504
505 pub fn borrow_decode<
506 'de,
507 Context,
508 D: BorrowDecoder<'de, Context = Context>,
509 L: BorrowDecode<'de, Context>,
510 R: BorrowDecode<'de, Context>,
511 >(
512 decoder: &mut D,
513 ) -> Result<Either<L, R>, DecodeError> {
514 let is_left = bool::borrow_decode(decoder)?;
515 Ok(if is_left {
516 Either::Left(L::borrow_decode(decoder)?)
517 } else {
518 Either::Right(R::borrow_decode(decoder)?)
519 })
520 }
521
522 #[cfg(test)]
523 mod tests {
524 use bincode::{decode_from_slice, encode_to_vec};
525
526 use super::*;
527
528 #[derive(Encode, Decode)]
529 struct Wrapper(#[bincode(with = "crate::either")] Either<String, u32>);
530
531 #[test]
532 fn test_roundtrip_left() {
533 let cfg = bincode::config::standard();
534
535 let either1 = Wrapper(Either::Left("hello".to_string()));
536
537 let either2: Wrapper = decode_from_slice(&encode_to_vec(&either1, cfg).unwrap(), cfg)
538 .unwrap()
539 .0;
540
541 assert_eq!(either1.0, either2.0);
542 }
543
544 #[test]
545 fn test_roundtrip_right() {
546 let cfg = bincode::config::standard();
547
548 let either1 = Wrapper(Either::Right(42u32));
549
550 let either2: Wrapper = decode_from_slice(&encode_to_vec(&either1, cfg).unwrap(), cfg)
551 .unwrap()
552 .0;
553
554 assert_eq!(either1.0, either2.0);
555 }
556 }
557}
558
559pub mod smallvec {
560 use ::smallvec::Array;
561
562 use super::*;
563
564 pub fn encode<E: Encoder, A: Array<Item = impl Encode>>(
565 vec: &SmallVec<A>,
566 encoder: &mut E,
567 ) -> Result<(), EncodeError> {
568 usize::encode(&vec.len(), encoder)?;
569 for item in vec {
570 Encode::encode(item, encoder)?;
571 }
572 Ok(())
573 }
574
575 pub fn decode<Context, D: Decoder<Context = Context>, A: Array<Item = impl Decode<Context>>>(
576 decoder: &mut D,
577 ) -> Result<SmallVec<A>, DecodeError> {
578 let len = usize::decode(decoder)?;
579 let mut vec = SmallVec::with_capacity(len);
580 for _ in 0..len {
581 vec.push(Decode::decode(decoder)?);
582 }
583 Ok(vec)
584 }
585
586 pub fn borrow_decode<
587 'de,
588 Context,
589 D: BorrowDecoder<'de, Context = Context>,
590 A: Array<Item = impl BorrowDecode<'de, Context>>,
591 >(
592 decoder: &mut D,
593 ) -> Result<SmallVec<A>, DecodeError> {
594 let len = usize::decode(decoder)?;
595 let mut vec = SmallVec::with_capacity(len);
596 for _ in 0..len {
597 vec.push(BorrowDecode::borrow_decode(decoder)?);
598 }
599 Ok(vec)
600 }
601
602 #[cfg(test)]
603 mod tests {
604 use bincode::{decode_from_slice, encode_to_vec};
605
606 use super::*;
607
608 #[test]
609 fn test_roundtrip() {
610 let cfg = bincode::config::standard();
611
612 #[derive(Encode, Decode)]
613 struct Wrapper(#[bincode(with = "crate::smallvec")] SmallVec<[u32; 4]>);
614
615 let vec1 = Wrapper(SmallVec::from_slice(&[1u32, 2, 3, 4, 5]));
616
617 let vec2: Wrapper = decode_from_slice(&encode_to_vec(&vec1, cfg).unwrap(), cfg)
618 .unwrap()
619 .0;
620
621 assert_eq!(vec1.0, vec2.0);
622 }
623 }
624}
625
626pub mod owned_cow {
627 use std::borrow::Cow;
632
633 use super::*;
634
635 #[allow(clippy::ptr_arg)]
636 pub fn encode<E, T>(cow: &Cow<'_, T>, encoder: &mut E) -> Result<(), EncodeError>
637 where
638 E: Encoder,
639 T: ToOwned + ?Sized,
640 for<'a> &'a T: Encode,
641 {
642 cow.encode(encoder)
643 }
644
645 pub fn decode<'cow, Context, D, T>(decoder: &mut D) -> Result<Cow<'cow, T>, DecodeError>
646 where
647 D: Decoder<Context = Context>,
648 T: ToOwned + ?Sized,
649 <T as ToOwned>::Owned: Decode<Context>,
650 {
651 Decode::decode(decoder)
652 }
653
654 pub fn borrow_decode<'de, 'cow, Context, D, T>(
655 decoder: &mut D,
656 ) -> Result<Cow<'cow, T>, DecodeError>
657 where
658 D: BorrowDecoder<'de, Context = Context>,
659 T: ToOwned + ?Sized,
660 <T as ToOwned>::Owned: Decode<Context>,
661 {
662 Decode::decode(decoder)
663 }
664}