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